Reuse of a LINQ query
Yes, you can write a function containing the query you want to reuse, which takes and returns an IQueryable<T>
public IQueryable<T> ContainsEmpty(IQueryable<T> query)
{
return query.Where(x => x.Contains(""));
}
Now you can reuse it:
query1 = ContainsEmpty(query1);
query2 = ContainsEmpty(another);
It depends. There's two Where
methods, Enumerable.Where
and Queryable.Where
. If you're applying the .Where
to an IEnumerable
than the first one is called, if you're applying it to an IQueryable
the second one is called.
Since Enumerable.Where
takes in a Func
, it isn't reusable. Since Queryable.Where
takes in an expression, it is reusable. You can do so as follows:
var x = new List<string>().AsQueryable();
var query = x.Where (n => n.Contains("some string"));
//Extract the lambda clause
var expr = query.Expression;
var methodExpr = (MethodCallExpression)expr;
var quoteExpr = (UnaryExpression)methodExpr.Arguments[1];
var funcExpr = (Expression<Func<string, bool>>)quoteExpr.Operand;
You can then later re-apply the where expression:
var query2 = x.Where(funcExpr);
I wrote a library to address exactly this concern, it's called CLinq and you can find an implementation for the EntityFramework here: https://www.nuget.org/packages/CLinq.EntityFramework
It allows to create query snippets and use them everywhere you in a linq query. Following the example of Hamid, create the following expression:
System.Linq.Expressions.Expression<Func<Foo, bool>> selector = x => x.Contains("");
You can now use this query everywhere in your linq queries like this:
query.AsComposable().Where(o => selector.Pass(o));
Additionally to this simple example you're also able to combine your query snippets:
query.AsComposable().Where(o => selector.Pass(o) || anotherSelector.Pass(o));
or even merge them together:
query.AsComposable().Where(o => anotherSelector.Pass(selector.Pass(o)));
There's some more features, but I think it's really helpful, so check it out :)
You can store it in a variable. If you are working with IQueryable
then use:
System.Linq.Expressions.Expression<Func<Foo, bool>> selector = x => x.Contains("");
If you are using IEnumerable
then use:
Func<Foo, bool> selector = x => x.Contains("");
And use it in your query:
query.Where(selector);