I have several LINQ-to-Entities queries that fall into the same two tables and have the same conditions. What I'm trying to do is share the where clause between multiple requests. For example, let's say I have this:
from t0 in db.Table0 from t1 in db.Table1 from t2 in db.Table2 where t0.Field7 == 'something' && t1.Field1 > t2.Field3 && t2.NavigationProperty(t => t.Field4 == t1.Field2).Any() select t0
I would like to say something like this:
Func<Table1, Table2, bool> specialCondition = (t1, t2) => t1.Field1 > t2.Field3 && t2.NavigationProperty(t => t.Field4 == t1.Field2).Any(); from t0 in db.Table0 from t1 in db.Table1 from t2 in db.Table2 where t0.Field7 == 'something' && specialCondition(t1, t2) select t1
This generates The LINQ expression node type 'Invoke' is not supported in LINQ to Entities. that makes sense. It cannot parse arbitrary .NET function / delegate code into something that it can pass to the database.
Everything I read on the Internet says that expression trees, however, may work just fine. My problem is that I can declare it (it is almost the same syntax as the function), I do not know how to use it.
Expression<Func<Table1, Table2, bool>> specialCondition = (t1, t2) => t1.Field1 > t2.Field3 && t2.NavigationProperty(t => t.Field4 == t1.Field2).Any();
What should I do with this? How to pass it LINQ2EF?
Update: A working solution with LinqKit in accordance with the @Mic recommendation, derived from NuGet (note the .AsExpandable() and .Invoke and the edited imported reference and LinqKit namespace):
Expression<Func<Table1, Table2, bool>> specialCondition = (t1, t2) => t1.Field1 > t2.Field3 && t2.NavigationProperty(t => t.Field4 == t1.Field2).Any(); from t0 in db.Table0.AsExpandable() from t1 in db.Table1 from t2 in db.Table2 where t0.Field7 == 'something' && specialCondition.Invoke(t1, t2) select t1
Validation in LinqPad, both the first fully integrated version and the final version of Exq LinqKit express the same SQL and results. Many thanks to all of you for your suggestions and help.