【问题标题】:What is the best practice to implement advanced search using Entity Framework?使用 Entity Framework 实现高级搜索的最佳实践是什么?
【发布时间】:2013-11-03 17:57:37
【问题描述】:

我使用两种不同的方法来实现高级搜索,每种方法都有其优点和缺点。

用户可以使用 3 个参数(姓名、姓氏和手机)执行高级搜索。

我尝试的第一种方法是检查用户提供了哪些参数;这需要我进行 8 次 ifelse 检查(2 ^ 参数个数),并且在每种情况下,我编写一个单独的查询来接受相应的参数,例如,如果用户在 where 子句中输入了姓名和姓氏查询将如下所示:

where(x=>x.name.contains(name) && x.familyname.contains(familyname))

或者在另一种情况下,如果用户只输入了手机,查询的 where 子句将如下所示:

where(x=>x.mobile==mobile)

这种方式的优点是我访问了一次数据库,但缺点是我必须编写更多的代码。

我尝试的第二种方法是我声明了一个IQueryable<> 对象,我首先将数据无条件地输入它,然后我逐个检查搜索参数,如果其中任何一个具有值,我过滤IQueryable使用该值,最后我执行.ToList()。这种方式的优点是代码少得多,但会两次访问数据库,这是一个问题。

这里是第二种方式的代码示例:

List<ShoppingCardForGridView> list_ShoppingCardForGridView = 
    new List<ShoppingCardForGridView>();
IQueryable<ShoppingCardForGridView> outQuery = 
    from x in db.ShoppingCards
    orderby x.TFDateBackFromBank descending
    where x.TFIsPaymentCompleted == true
    select new ShoppingCardForGridView
    {
        Id = x.Id,
        TFCustomerFullName = 
            x.Customer.TFName + " " + x.Customer.TFFamilyName,
        TFDateBackFromBank = x.TFDateBackFromBank.Value,
        TFIsDelivered = x.TFIsDelivered,
        TFItemsPriceToPay = x.TFItemsPriceToPay,
        TFDateBackFromBankPersian = x.TFDateBackFromBankPersian

    };

if (!string.IsNullOrEmpty(CustomerFullName))
{
    outQuery = outQuery.Where(x => 
        x.TFCustomerFullName.Contains(CustomerFullName));
}
if (!string.IsNullOrEmpty(IsDelivered))
{
    bool deliveryStatus = Convert.ToBoolean(IsDelivered);
    outQuery = outQuery.Where(x => x.TFIsDelivered == deliveryStatus);
}
list_ShoppingCardForGridView = outQuery.ToList();

我想知道是否有更好的方法或最佳实践来使用实体框架执行高级搜索?

【问题讨论】:

  • 我认为这可能更适合CodeReview
  • 你需要构建一个表达式树。
  • @SLaks 任何代码示例或好的教程?
  • 我看不到您两次访问数据库的方式。那里只有一次迭代。
  • @SLaks 我认为没有任何必要。他已经拥有的代码比手动构建表达式更简单,同样有效。

标签: c# entity-framework search


【解决方案1】:

您的第二个解决方案没有多次访问数据库。请记住,IQueryable 对象是查询本身,而不是查询的结果。执行被推迟到查询被实际迭代。基于各种if 检查有条件地附加多个Where 子句正在更改查询本身,而不是处理查询的结果(因为在那个时间点没有结果)。

您可以在数据库上使用分析器来验证只有一个查询正在执行,并且一个查询包含该一次的所有过滤。

这是一个相当普遍的模式;我已经在许多实例中使用它来制作自定义搜索页面。

【讨论】:

  • 那么我的第二种方法是最佳实践吗?
  • @Karamafrooz 这是一个很好的方法,它明显正确、同样有效、可扩展且易于编写,不像第一个非常麻烦、容易出错且不可扩展。这应该使决定相当明显。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-09-06
  • 2022-01-11
  • 1970-01-01
  • 2020-12-15
  • 1970-01-01
  • 2018-06-14
  • 1970-01-01
相关资源
最近更新 更多