LINQ to SQL PredicateBuilder - PullRequest
       9

LINQ to SQL PredicateBuilder

9 голосов
/ 27 октября 2009

Я использую PredicateBuilder, как показано здесь http://www.albahari.com/nutshell/predicatebuilder.aspx, все работает отлично, и теперь я могу генерировать динамические выражения LINQ to SQL, но я не понимаю, почему, когда я нахожусь в цикле, как это:

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

Почему я должен использовать эту временную переменную? Я пытаюсь использовать переменную итератора "f", но она получает только последнее значение в списке для каждой итерации, как будто оно передается по ссылке ...

Ответы [ 2 ]

10 голосов
/ 27 октября 2009

Поскольку PredicateBuilder создает выражение, которое будет выполнено в более поздний момент времени. Когда компилятор создает замыкание для делегата, он находит все значения, созданные в текущей области, и переносит их также в замыкание. Поскольку InstrumentID является типом значения (int), инициализация и копирование значения означает, что каждый делегат / закрытие будет нести это значение вместе с ним. Если вы не создаете копию значения каждый раз, выражение просто будет иметь буквальную ссылку на f.InstrumentID, а не на его базовое значение. Таким образом, позже, когда выражение фактически выполнено, вычисляется f.InstrumentID, и оно будет выглядеть так, как оно было установлено в последний раз, что является последней итерацией.

2 голосов
/ 27 октября 2009

Потому что это не оценка условия, а просто построение выражения. Выражение связывается с переменной, определенной в foreach, которая сохраняет свою ссылку на протяжении всего цикла. Переопределение его с помощью временной переменной заставляет каждое выражение использовать другую переменную, что заставляет его ссылаться на экземпляр со значением на каждой итерации, а не на то, чтобы все итерации ссылались на одну ссылку и имели значение только последней итерации.

...