У цьому випадку важливо розрізняти IQueryable<T>
і IEnumerable<T>
. Коротше кажучи IQueryable<T>
, обробляється постачальником LINQ для доставки оптимізованого запиту. Під час цього перетворення не підтримуються всі C # оператори, оскільки або неможливо перевести їх у запит конкретного резервного запиту (наприклад, SQL), або тому, що реалізатор не передбачив необхідності оператора.
На противагу цьому IEnumerable<T>
виконується проти конкретних предметів і, отже, не трансформується. Отже, досить часто зустрічається, що конструкції, з якими можна використовувати IEnumerable<T>
, не можуть бути використані, IQueryable<T>
а також ті, що IQueryables<T>
підтримуються різними постачальниками LINQ, не підтримують однаковий набір функцій.
Однак є деякі вирішення (на зразок відповіді Філа ), які змінюють запит. Крім того, як більш загальний підхід можна повернутися до попереднього, IEnumerable<T>
перш ніж продовжувати специфікацію запиту. Це, однак, може спричинити показник продуктивності - особливо, коли його застосовують для обмежень (наприклад, де пункти). Навпаки, при роботі з трансформаціями, показник ефективності набагато менший, іноді навіть не існує - залежно від вашого запиту.
Отже, наведений вище код також може бути переписаний так:
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;