Reputation: 89
I've read a bunch of articles on putting LINQ expressions together, but they only seem to cover and's and or's. I have this solution implemented:
http://blogs.msdn.com/b/meek/archive/2008/05/02/linq-to-entities-combining-predicates.aspx
How do I write this code so that it works?
Expression<Func<Crop, bool>> chooseOranges = crop => crop.IsOrange;
Expression<Func<Farm, bool>> selectFarm = farm => farm.HasCows;
selectFarm = selectFarm.And(farm => farm.Crops.Any(chooseOranges);
It compiles, but at runtime it throws a .NET 1025 error. If I replaced chooseOranges with the literal text it would work, but chooseOranges is built piece by piece with business logic. It seems like the code I linked above relies on the various Expression.Foo() functions, but I couldn't find one that would help.
Upvotes: 1
Views: 786
Reputation: 13104
Use LinqKit's ability to evaluate nested expressions and return a single expression usable by any provider that would support the same expression written out:
Expression<Func<Crop, bool>> chooseOranges = crop => crop.IsOrange;
Expression<Func<Farm, bool>> selectFarm = farm => farm.HasCows;
Expression<Func<Farm, bool>> combined = (farm) => selectFarm.Invoke(farm) && farm.Crops.Any(inner => chooseOranges.Invoke(inner));
combined = combined.Expand();
Upvotes: 2
Reputation: 110221
I would write it like this:
Expression<Func<Crop, bool>> chooseOranges = crop => crop.IsOrange;
Expression<Func<Farm, bool>> selectFarm = farm => farm.HasCows;
IQueryable farmQuery = GetQuery();
farmQuery = farmQuery.Where(selectFarm);
farmQuery = farmQuery.Where(farm => farm.Crops.Any(chooseOranges);
Each row must meet both criteria to be in the result, so that's And.
For Or, I did that over there.
Upvotes: 1