Почему LINQ-Entites распознает мой пользовательский метод? - PullRequest
9 голосов
/ 20 апреля 2010

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

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

Ответы [ 2 ]

6 голосов
/ 20 апреля 2010

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

 Where(Func<WorkOrder, bool>

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

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

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

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

[Редактировать (BlueRaja)]

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

Существуют перегрузки Where для обоих типов. .Where(MyCustomMethod) вызывает Func<WorkOrder, bool>, тогда как .Where(o => MyCustomMethod(o)) вызывает Expression<Func<WorkOrder, bool>>.

1 голос
/ 20 апреля 2010

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...