Передача в лямбда-выражении Where - PullRequest
0 голосов
/ 03 января 2011

Я заметил сегодня, что если я сделаю это:

var items = context.items.Where(i => i.Property < 2);
items = items.Where(i => i.Property > 4);

Как только я обращаюсь к элементам var, он выполняет только первую строку в качестве вызова данных, а затем выполняет второй вызов в памяти. Однако, если я сделаю это:

var items = context.items.Where(i => i.Property < 2).Where(i => i.Property > 4);

Я получаю только одно выражение, выполненное в контексте, который включает оба оператора where. У меня есть множество переменных, которые я хочу использовать для построения выражения для лямбда-выражения linq, но их наличие или отсутствие изменяет выражение так, что для выполнения всех случаев мне понадобится повторное количество условных чисел. Я подумал, что мог бы просто добавить оператор Where (), как в моем первом примере выше, но это не заканчивается одним выражением, которое содержит все критерии. Поэтому я пытаюсь создать только саму лямбду как таковую:

//bogus syntax
if (var1 == "something")
    var expression = Expression<Func<item, bool>>(i => i.Property == "Something);
if (var2 == "somethingElse")
    expression = expression.Where(i => i.Property2 == "SomethingElse");

А затем передайте это в где мой контекст. Детали для оценки. А) это правильно, и Б) если так, как ты это делаешь?

РЕДАКТИРОВАТЬ:

IQueryable assessments = assessmentContext.Assessments;
metAssessments = metAssessments.Take(pageSize);

результат в

SELECT [Fields] <== edited
FROM [dbo].[Assessment] AS [t0]
INNER JOIN [dbo].[AssessmentComment] AS [t1] ON [t1].[ID] = [t0].[AssessmentID] <== because of load options

Почему нет верхнего x (как представлено pageSize)?

Ответы [ 3 ]

2 голосов
/ 03 января 2011

Какой поставщик запросов вы используете? Для любого разумного поставщика ваш первый пример должен выполняться на источнике (не в памяти) как соединение двух условий в каждом из ваших Where s.

Что касается вашего вопроса, нет, это неправильный способ приступить к созданию Expression вручную. Ваше первое определение в порядке, но для построения соединения вам нужно использовать Expression.AndAlso.

Люди уже завернули это в библиотеку для вашего использования. См. PredicateBuilder .

0 голосов
/ 03 января 2011

Я бы предположил, что причина, по которой первое и второе отличаются, состоит в том, что items уже получил доступ к данным в этой точке.Если вы сделаете объект items наследуемым от IQueryable, вы на самом деле ничего не будете выполнять против контекста, пока не получите доступ к элементам в коллекции.

0 голосов
/ 03 января 2011

Используйте PredicateBuilder для динамического построения запроса.

...