Isaac Bolinger
Isaac Bolinger

Reputation: 7388

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

Upvotes: 5

Views: 1420

Answers (2)

Jeff Mercado
Jeff Mercado

Reputation: 134841

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) )
}

Upvotes: 1

Polity
Polity

Reputation: 15130

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#

Upvotes: 5

Related Questions