0

Combining predicates like this causes stack overflow exception when EF query is executed. What is wrong with this?

Func<Item, bool> wherePredicate = i => i.isDeleted;
Func<Item, bool> wherePredicate2 = i => i.isExpired;

wherePredicate = i=> wherePredicate(i) || wherePredicate2(i);
John L.
  • 1,825
  • 5
  • 18
  • 45
  • Because `wherePredicate` calls itself... – haim770 Nov 28 '17 at 20:59
  • @haim770 I have a dynamic scenario where the final predicate is determined by evaluating a lot of cases. How else can I combine them? – John L. Nov 28 '17 at 21:05
  • You are creating recursive lambda. But `Func<...>`s are not a proper predicate type for EF query anyway. For combining expression predicates, use any predicate builder library (from LinqKit or similar). – Ivan Stoev Nov 28 '17 at 21:06
  • First, for EF you need `Expression>` in order to match `IQueryable`. You can use LinqKit to try and combine the predicates. – haim770 Nov 28 '17 at 21:08
  • Build the predicate using [this](https://stackoverflow.com/a/14622200/861716). – Gert Arnold Nov 28 '17 at 22:06
  • Possible duplicate of [Dynamic where clause (OR) in Linq to Entities](https://stackoverflow.com/questions/14621450/dynamic-where-clause-or-in-linq-to-entities) – Eris Nov 28 '17 at 22:17

1 Answers1

0

You've created recursive loop, probably by accident. With:

wherePredicate = i=> wherePredicate(i) || wherePredicate2(i);

you are just defining anonymous function in which i=> wherePredicate(i) (...) will be invoked, so it will invoke itself. The common rule like "everything on right side of '=' will be called before assignment" do not apply there as you might have thought, because a function it's what gets assigned, not its result.

What's more (you tagged Entity Framework) - it won't work in .Where() clause. Short answer - EF do not know how to invoke Func<> in database. Long answer - see LINQKit which will help you in defining reusable predicates. Strange coincidance - your problem is almost literally explained in "combining-expressions" section.

baterja
  • 1
  • 6