Почему LINQ-to-Entites распознает мой собственный метод?
Это работает:
Entities.WorkOrderSet.Where(MyCustomMethod);
Это не означает:
Entities.WorkOrderSet.Where(o => MyCustomMethod(o));
( [Изменить] Даже без new
он не работает)
Я понимаю, почему вторая не работает - , но почему в мире первая работа!? Не следует ли мне получать "LINQ-to-Entities", который не распознает метод.. "во время выполнения, как со вторым?
Для справки, здесь MyCustomMethod
public bool MyCustomMethod(WorkOrder workOrder)
{
return !workOrder.WorkOrderNum.StartsWith("A", StringComparison.CurrentCultureIgnoreCase);
}
Использование EF1, а не EF4
Ответы
Ответ 1
Сначала работает, потому что он является методом расширения и выполняет запрос как func, а затем фильтрует ваш список see здесь.
Таким образом, в общем случае он автоматически добавляет, где
Where(Func<WorkOrder, bool>
Второе не потому, что оно подталкивает ваше утверждение where к db. Когда вычисляется лямбда-выражение, оно расширяется следующим образом:
Where( Expresion<Func<WorkOrder, bool>>)
Вот хорошая статья которая объясняет Выражения vs Func
Вот еще одно сообщение, которое помогает объяснить разницу
[Изменить (BlueRaja)]
Это новое редактирование выглядит правильным. Чтобы прояснить: кажется, что Func<WorkOrder, bool>
неявно приписано к Expression<Func<WorkOrder, bool>>
, но не наоборот.
Существуют перегрузки Where
для обоих типов. .Where(MyCustomMethod)
вызывает Func<WorkOrder, bool>
one, тогда как .Where(o => MyCustomMethod(o))
вызывает Expression<Func<WorkOrder, bool>>
one.
Ответ 2
Просто создавая это как "ответ" здесь, вместо комментария.
Я думаю, что это новая функция в .NET 4, где структура понимает, что эта функция не может быть переведена на SQL, но может быть легко обработана в памяти. Таким образом, он получает весь набор данных на локальном компьютере и продолжает обработку запросов.
Это ваш первый фрагмент, когда он переводится в дерево выражений, прямо скажет, что он запускает внешний метод, в то время как ваш второй фрагмент не так "прямой". Полагаю, именно поэтому в первом случае L2E может легко понять, что происходит, и решить, что делать, а во втором случае "думает", что лучше отправить исключение и позволить разработчикам почесывать головы еще немного _ _ ^