В этом случае важно различать IQueryable<T>
и IEnumerable<T>
. Короче говоря IQueryable<T>
, обрабатывается поставщиком LINQ для доставки оптимизированного запроса. Во время этого преобразования поддерживаются не все операторы C #, так как либо невозможно перевести их в специфичный для внутреннего интерфейса запрос (например, SQL), либо потому, что разработчик не предвидел необходимость в операторе.
В отличие от IEnumerable<T>
выполненного против конкретных объектов и, следовательно, не будет трансформироваться. Таким образом, довольно распространено, что конструкции, которые можно использовать с IEnumerable<T>
, не могут быть использованы, IQueryable<T>
а также те, которые IQueryables<T>
поддерживаются различными поставщиками LINQ, не поддерживают один и тот же набор функций.
Однако есть некоторые обходные пути (например , ответ Фила ), которые изменяют запрос. Кроме того, в качестве более общего подхода можно вернуться к описанию, IEnumerable<T>
прежде чем продолжить со спецификацией запроса. Это, однако, может привести к снижению производительности - особенно при использовании его в ограничениях (например, в предложениях where). Напротив, при работе с преобразованиями снижение производительности намного меньше, а иногда и вовсе отсутствует - в зависимости от вашего запроса.
Таким образом, приведенный выше код также можно переписать так:
return this.ObjectContext.BranchCostDetails
.AsEnumerable()
.Where(
b => b.TarrifId == tariffId && b.Diameter == diameter
|| (b.TarrifId==tariffId && !string.IsNullOrWhiteSpace(b.Diameter))
||(!b.TarrifId.HasValue) && b.Diameter==diameter
);
ПРИМЕЧАНИЕ. Этот код окажет более сильное влияние на производительность, чем ответ Фила . Тем не менее, это показывает принцип.
List<string> my = new List<string>(); var i = from m in my where !string.IsNullOrWhiteSpace(m) select m;