Почему LINQ-to-Entites распознает мой пользовательский метод?

Это работает:

Entities.WorkOrderSet.Where(MyCustomMethod);

Это не делает:

Entities.WorkOrderSet.Where(o => MyCustomMethod(o));

([Редактирование] Даже без new, это не работает),

Я понимаю, почему второе не работает - но почему в мире делает первую работу!? Разве я не должен добираться, "LINQ к объектам не распознает метод..." во времени выполнения, как со вторым?

Для ссылки вот MyCustomMethod

public bool MyCustomMethod(WorkOrder workOrder)
{
    return !workOrder.WorkOrderNum.StartsWith("A", StringComparison.CurrentCultureIgnoreCase);
}

Используя EF1, не EF4

9
задан BlueRaja - Danny Pflughoeft 5 July 2011 в 11:22
поделиться

2 ответа

Сначала работает, потому что является методом расширения и выполняет запрос как функцию, а затем фильтрует ваш список , см. Здесь . В общем, это автоматически приведет к приведению where к

 Where(Func<WorkOrder, bool>

Second, потому что он подталкивает ваш оператор where к db. Когда вычисляется лямбда-выражение, оно раскрывается следующим образом:

Where( Expresion<Func<WorkOrder, bool>>)

Вот хорошая статья , в которой объясняются Выражения и Func

. Вот еще один пост SO, который помогает объяснить разница

[Изменить (BlueRaja)]

Это новое изменение кажется правильным. Чтобы уточнить: похоже, что Func неявно может быть приведено к Expression > , но не наоборот.

Имеются перегрузки , где для обоих типов. . Где (MyCustomMethod) вызывает Func , тогда как .Where (o => MyCustomMethod (o)) вызывает Выражение > one.

6
ответ дан 4 December 2019 в 23:05
поделиться

Просто формирую здесь это как «ответ» вместо комментария.

Я думаю, что это новая функция в .NET 4, где структура понимает, что эта функция не может быть переведена на SQL, но может быть легко обработана в памяти. Таким образом, он передает весь набор данных на локальный компьютер и продолжает обработку запроса.

Дело в том, что ваш первый фрагмент, преобразованный в дерево выражений, прямо скажет, что он запускает внешний метод, а ваш второй фрагмент - нет. так "прямо". Полагаю, поэтому в первом случае L2E может легко понять, что происходит, и решить, что делать, а во втором случае он «думает», что лучше отправить исключение и позволить разработчикам еще немного почесать голову ^ _ ^

1
ответ дан 4 December 2019 в 23:05
поделиться
Другие вопросы по тегам:

Похожие вопросы: