Rod*_*rez 6 c# linq entity-framework
如何检测是否应用IQueryable<T>了where过滤器?
在这段代码中,我需要以编程方式知道queryFiltered已经where应用了它而query不是
IQueryable<Customer> query = Context.Customers;
IQueryable<Customer> queryFiltered = Context.Customers
.Where(c=>c.Name.Contains("ABC"));
Run Code Online (Sandbox Code Playgroud)
您将必须解析在实现上Expression从Expression属性返回的内容IQueryable<T>.
在爬网时,您将不得不查询被调用的Queryable.Where方法Expression.
另请注意,虽然Queryable.Where这将是检测where过滤器的最常用方法,但查询语法允许使用其他实现(取决于using指令中使用的命名空间); 如果你有一些没有使用Queryable.Where扩展方法的东西,那么你必须明确地寻找它(或者使用更通用的过滤Where方法来获取IQueryable<T>并返回一个方法IQueryable<T>).
在ExpressionVisitor类(如由萨那托斯指出的)提供了爬行的一个非常简单的方法Expression树,我强烈建议使用这种方法为处理您的基本Expression树.
值得注意的是,ExpressionVisitor类实现需要在类级别上存储和公开状态.因此,最好(IMO)创建一次性执行操作的内部类,然后使用公共方法创建ExpressionVisitor每次的新实例; 这将有助于处理变异状态,如果正确完成,将允许该方法也是线程安全的(如果这是您的关注).
如果您使用的是 C# 4.0,则可以使用以下示例代码:使用 ExpressionVisitor 获取所有“where”调用
它基于ExpressionVisitor. 它“访问” a 的各个元素IQueryable<T>以找到Where零件。看起来很简单。
如果您使用的是 C# = 3.5,则可以使用ExpressionVisitorMSDN 的“如何:实现表达式树访问者”中的示例以及WhereFinder上一个链接中的示例(它们可以正常工作,刚刚经过测试)
使用代码:
var wf = new WhereFinder();
var wheres = wf.GetWhere(query.Expression);
if (wheres.Any())
{
// There are Where in the query!
}
Run Code Online (Sandbox Code Playgroud)
如果您(正确地)与Rune FS, 一样偏执WereFinder.VisitMethodCall,请将 更改if为
if (expression.Method.Name == "Where" && expression.Method.DeclaringType.FullName == "System.Linq.Queryable")
Run Code Online (Sandbox Code Playgroud)