C# 使用实体框架实现高级搜索的最佳实践是什么?
我使用两种不同的方法来实现高级搜索,每种方法都有其优缺点 用户可以使用3个参数(姓名、familyname和手机)执行高级搜索 我尝试的第一种方法是检查哪些参数是由用户提供的;这需要我执行8个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
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这是一种很好的方法,显然是正确的,同样有效,可扩展,易于编写,不像第一种方法非常麻烦,容易出错,而且不可扩展。这将使决定变得相当明显。