Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Trouble with using predicatebuilder in a foreach loop

I'm having trouble building predicates in a foreach loop. The variable that contains the value the enumerator is currently on is something I need to put in the predicate.

So,

IQueryable query = getIQueryableSomehow();
Predicate = PredicateBuilder.False<SomeType>();
foreach (SomeOtherType t in inputEnumerable)
{
    Predicate = Predicate.Or( x => x.ListInSomeType.Contains(t) )
}
var results = query.Where(Predicate);

is failing me. The expressions ORed together in Predicate basically all use the same t from inputEnumerable, when of course I want each expression ORed into Predicate to use a different t from inputEnumerable.

I looked at the predicate in the debugger after the loop and it is in what looks like IL. Anyways each lambda in there looks exactly the same.

Can anyone tell me what I might be doing wrong here?

Thanks,

Isaac

like image 592
Isaac Bolinger Avatar asked Oct 19 '11 02:10

Isaac Bolinger


2 Answers

The problem is how closures work. You have to copy the SomeOtherType t instance in a local like:

foreach (SomeOtherType t in inputEnumerable) 
{ 
    SomeOtherType localT = t;
    Predicate = Predicate.Or( x => x.ListInSomeType.Contains(localT) ) 
}

For more information, please see: Captured variable in a loop in C#

like image 87
Polity Avatar answered Sep 17 '22 16:09

Polity


You're closing over the loop variable. Declare a local variable for your SomeOtherType and use that in your predicate.

foreach (SomeOtherType t in inputEnumerable)
{
    var someOtherType = t;
    Predicate = Predicate.Or( x => x.ListInSomeType.Contains(someOtherType) )
}
like image 22
Jeff Mercado Avatar answered Sep 18 '22 16:09

Jeff Mercado