我正在使用实体框架来处理MVC应用程序中的数据库:我使用start表单中的几个字段创建了一个搜索引擎,并设置了来自用户角色的权限,因此创建select的例程声明正在增长,所以有时我会遇到这种情况。 在我做出选择之前:
var orders = db.Orders.Where(ord => ord.Channel == 1 || ord.Channel == 2);
在源代码之后,在某些情况下,用户类型,过滤器组合等,我必须更改此过滤器或删除此条件
orders = db.Orders.Where(ord => ord.Channel == 1);
这只是一个简单的例子,因为这样做我松开了我在Linq表达式树中完成的其他过滤器,并且因为我要求经常添加功能,所以很难重新组织所有代码来测试所有为表达式树添加条件之前的先决条件,所以我想知道是否可以在添加之后以及在SQL查询中解析和转换树之前删除linq表达式树中的语句
luca
答案 0 :(得分:1)
假设我正确理解了您的问题,我认为最简单的方法是推迟创建查询,直到您收集了所有需要知道查询应该是什么样的数据,即在这种情况下它意味着您构建只有在您已经知道是否确实需要应用条件之后才进行查询。
如果您无法推迟查询的创建(在我看来,这就是您所说的),但您仍然可以预测以后可能需要删除哪些条件,我会考虑在查询中引入布尔标记,例如根据您的查询摘要:
var orders = db.Orders.Where( ord =>
(isFirstConditionRelevant && ord.Channel == 1)
|| (isSecondConditionRelvant && ord.Channel == 2));
变量'isFirstConditionRelevant'和'isSecondConditionRelevant'最初将被设置为true并且将被查询表达式捕获,但是如果您需要,您可以在稍后的时间点(例如,在执行查询之前)设置为false相应的条件无效。请注意,使用此方法,查询的SQL转换仍将包含条件,但它还将包含每个标记的参数,该参数将在服务器执行查询时将布尔逻辑短路。
另请注意,条件中的任何常量(例如,'ord.Channel == 1'中的'1')将在SQL中转换为常量。我建议使用变量,因为这将在SQL查询中引入参数,这可能会增加查询计划可以在服务器上重用的机会。
另一种可能有用的方法是利用对查询中表达式变量的引用的支持,例如:你可以传递Expression>类型的变量到Where子句,稍后将变量的值替换为右谓词。如果我没记错的话,LINQ to Entities通过将AsQueryable运算符应用于查询中的集合,支持使用表达式变量作为嵌套集合的谓词条件。否则,您可以利用LINQ工具包提供的对AsExpandable的支持。您将找到有关此内容的更多信息,以及在LINQ Kit主页中使用对表达式变量的引用的示例:http://www.albahari.com/nutshell/linqkit.aspx。
我要考虑的第四个也是最复杂的方法是使用我自己的访问者(例如派生自System.Linq.Expressions.ExpressionVisitor)来重写LINQ表达式树(在这种情况下从谓词中删除条件)查询已执行。我没有一个表达访问者,它确实非常方便。相反,我可以提供一些指向解决问题不同部分的文章的指针:
希望这有帮助!