Каждый вызов Where
создает новый объект, который знает о вашем фильтре и последовательности, в которой он вызывается.
Когда у этого нового объекта запрашивается значение (а я намеренно нечеткиймежду итератором и итератором здесь) он будет запрашивать исходную последовательность для следующего значения, проверять фильтр и либо возвращать значение, либо итерацию обратно, запрашивая исходную последовательность для следующего значения и т. д.
Так что еслиВы звоните Where
50 раз (как в list.Where(...).Where(...).Where(...)
, в итоге вы получаете что-то, что должно увеличиваться и уменьшаться в стеке вызовов как минимум 50 раз для каждого возвращаемого элемента. Какое влияние это окажет на производительность? Я незнайте: вы должны измерить его.
Одна из возможных альтернатив - построить дерево выражений, а затем скомпилировать его в делегат в конце, и затем вызвать Where
.потребуются немного больше усилий, но это может в конечном итоге стать более эффективным. Фактически, это позволит вам изменить это:
list.Where(x => x.SomeValue == 1)
.Where(x => x.SomethingElse != null)
.Where(x => x.FinalCondition)
.ToList()
на
list.Where(x => x.SomeValue == 1 && x.SomethingElse != null && x.FinalCondition)
.ToList()
Если вы знаете, что вы просто собираетесь объединить множество фильтров "где", это может в конечном итоге оказаться более эффективным, чем проход по IQueryable<T>
.Как всегда, проверьте производительность самого простого решения, прежде чем делать что-то более сложное.