Determine Where IQueryable <T> Applies
How to determine if an IQueryable<T> where filter is applied?
In this code, I need to know programmatically that queryFiltered has where to it, and query does not
IQueryable<Customer> query = Context.Customers; IQueryable<Customer> queryFiltered = Context.Customers .Where(c=>c.Name.Contains("ABC")); You will have to IQueryable<T> Expression , which returns from Expression to IQueryable<T> .
You will need to query the Queryable.Where method when scanning the Expression tree.
Also note that although Queryable.Where will be the most common way to detect the where filter, the query syntax allows you to use other implementations (depending on what namespaces are used in using directives ); if you have something that does not use the Queryable.Where extension method, then you will have to look for it explicitly (or use a more general filtering method for the where method, which accepts IQueryable<T> and returns IQueryable<T> ).
ExpressionVisitor class (as indicated by xanatos ) is a very easy way to traverse the Expression tree, I highly recommend using this approach as a base for processing the Expression tree.
It should be noted that the storage and display of state at the class level requires the implementation of ExpressionVisitor classes. Because of this, it would be better (IMO) to create inner classes that perform a one-time action, and then have a public method that creates a new instance of ExpressionVisitor each time; this will help to cope with the mutating state and, if done correctly, will allow the method to be thread safe (if it bothers you).
If you are using C # 4.0, you can use this code example: Get all the 'where' calls using ExpressionVisitor
It is based on ExpressionVisitor . He "visits" the various IQueryable<T> elements to find Where parts. It seems simple enough.
If you are in C # = 3.5, you can use the ExpressionVisitor sample from the MSDN How-to Guide. Implementation of the visitor of the PLUS WhereFinder expression tree from the previous link (they work correctly together, just tested)
To use the code:
var wf = new WhereFinder(); var wheres = wf.GetWhere(query.Expression); if (wheres.Any()) { // There are Where in the query! } If you are (correct) as paranoid as Rune FS in WereFinder.VisitMethodCall , change if to
if (expression.Method.Name == "Where" && expression.Method.DeclaringType.FullName == "System.Linq.Queryable") The easiest way is to call q.Expression.ToString().Contains(".Where(") . As you can see, query.Expression.ToString().Contains(".Where(") returns false, and queryFiltered.Expression.ToString().Contains(".Where(") returns true.
You may need extra complexity if you consider other expressions to be "filtering", but this is also true for an approach that uses an expression.
There is something pretty hacked, I will give you, but it seems a lot easier.