Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/entity-framework/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用实体框架实现高级搜索的最佳实践是什么?_C#_Entity Framework_Search - Fatal编程技术网

C# 使用实体框架实现高级搜索的最佳实践是什么?

C# 使用实体框架实现高级搜索的最佳实践是什么?,c#,entity-framework,search,C#,Entity Framework,Search,我使用两种不同的方法来实现高级搜索,每种方法都有其优缺点 用户可以使用3个参数(姓名、familyname和手机)执行高级搜索 我尝试的第一种方法是检查哪些参数是由用户提供的;这需要我执行8个if和else检查(2^个参数),并在每个条件下编写一个单独的查询,该查询接受相应的参数,例如,如果用户输入了name&family name,则查询的where子句如下所示: where(x=>x.name.contains(name) && x.familyname.contain

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

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

我尝试的第一种方法是检查哪些参数是由用户提供的;这需要我执行8个
if
else
检查(2^个参数),并在每个条件下编写一个单独的查询,该查询接受相应的参数,例如,如果用户输入了name&family name,则查询的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();
列表\u ShoppingCardForGridView=
新列表();
IQueryable outQuery=
从db.ShoppingCards中的x开始
orderby x.TFDateBackFromBank降序
其中x.TFIsPaymentCompleted==true
选择新ShoppingCardForGridView
{
Id=x.Id,
TFCustomerFullName=
x、 Customer.TFName+“”+x.Customer.TFFamilyName,
TFDateBackFromBank=x.TFDateBackFromBank.Value,
TFIsDelivered=x.TFIsDelivered,
TFItemsPriceToPay=x.TFItemsPriceToPay,
TFDateBackFromBankPersian=x.TFDateBackFromBankPersian
};
如果(!string.IsNullOrEmpty(CustomerFullName))
{
outQuery=outQuery.Where(x=>
x、 TFCustomerFullName.Contains(CustomerFullName));
}
如果(!string.IsNullOrEmpty(IsDelivered))
{
bool deliveryStatus=Convert.ToBoolean(IsDelivered);
outQuery=outQuery.Where(x=>x.TFIsDelivered==deliveryStatus);
}
list_ShoppingCardForGridView=outQuery.ToList();
我想知道是否有更好的方法或最佳实践来使用entityframework执行高级搜索?

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

您可以在数据库上使用探查器来验证只执行了一个查询,并且一个查询包含了所有的过滤


这是一种相当普遍的模式;我在许多实例中使用过它来创建自定义搜索页面。

我认为这可能更适合。您需要构建一个表达式树。@SLaks任何代码示例或好的教程?我看不出您是如何两次命中DB的。这里只有一次迭代。@SLaks我看不出有任何必要这样做。他已经拥有的代码比手动构建表达式更简单,也同样有效。那么我的第二种方法是最佳实践吗?@Karamafrooz这是一种很好的方法,显然是正确的,同样有效,可扩展,易于编写,不像第一种方法非常麻烦,容易出错,而且不可扩展。这将使决定变得相当明显。