5

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

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

我尝试的第一种方法是检查用户提供了哪些参数;这需要我进行 8次if&else检查(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();

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

4

1 回答 1

7

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

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

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

于 2013-10-24T20:32:47.587 回答