Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

LINQ to SQL PredicateBuilder

Im using the PredicateBuilder as seen here http://www.albahari.com/nutshell/predicatebuilder.aspx, everything works great, and now i can genrate Dynamic LINQ to SQL expressions, but the thing that i dont understand is why when i am on a loop like this:

var inner = PredicateBuilder.False<MyType>();
foreach (var f in Filtermodel.InstrumentsFilterList.Where(s => s.isActive))
        {
          int temp = f.InstrumentID;
          inner = inner.Or(ud => ud.InstrumentId == temp);
        }

Why must i use that temp variable?, i try to use the "f" iterator variable but it only get the last value on the list for each iteration, like it is passed by reference...

like image 384
JOBG Avatar asked Feb 04 '23 08:02

JOBG


2 Answers

Because PredicateBuilder is building up an expression which will be executed at a later point in time. When the compiler is generating the closure for the delegate, it finds any values which are created in the current scope, and carries them into the closure as well. Since InstrumentID is a value type (int), initializing and copying the value means each delegate/closure will carry that value with it. If you don't create a copy of the value each time, the expression will simply have a literal reference to f.InstrumentID, not to its underlying value. So later on, when the expression is actually executed, f.InstrumentID is evaluated and it will come out as whatever it was last set to, which is the last iteration.

like image 166
Rex M Avatar answered Feb 23 '23 02:02

Rex M


Because it's not evaluating the condition, but simply building the expression. The expression binds to the variable defined in the foreach, which retains it's reference throughout the execution of the entire loop. Redefining it with a temporary variable forces each expression to use a different variable, which forces it to refer to the instance with the value at each iteration rather than having all iterations refer to the single reference and having the value of just the last iteration.

like image 23
tvanfosson Avatar answered Feb 23 '23 03:02

tvanfosson