Linq to Entities: использование функции вызывает несколько запросов

Я заметил очень странное поведение Linq to Entities, если в запросе Linq используются пользовательские функции (которые должным образом объявлены и подключены к Linq). Предположим, я выполняю оператор

var list = (from ts in context.Tests select MyFunction(ts.TestId));

Linq строит правильный запрос SQL Select, который правильно использует MyFunction. Но проблема в том, что Linq генерирует и отправляет этот оператор для каждой строки в таблице, а не отправляет его один раз! Я посмотрел в профилировщике SQL и обнаружил, что количество раз, когда этот оператор Select отправляется на сервер, равно количеству записей в тестовой таблице…

Что это? Это еще одна ошибка в Linq to Entities? Кто-нибудь знает обходной путь? Поскольку подобное поведение действительно делает функции на стороне базы данных непригодными для использования.


person Dmitry O    schedule 14.12.2010    source источник


Ответы (2)


Проблема решена. Выяснилось, что SQL Profiler неправильно сообщал о нескольких операторах. Linq фактически отправляет только 1 оператор.

person Dmitry O    schedule 15.12.2010

Но это именно то, что вы написали в своем запросе LINQ: выберите результат MyFunction(ts.TestId) для каждой строки в таблице Tests. Если в вашей таблице 25 строк, то ваш результирующий набор также будет содержать 25 записей, каждая из которых получена путем выполнения MyFunction.

Что вы на самом деле хотите сделать? Вы хотите выполнить MyFunction только один раз? Если да, то какой TestId вы хотите пройти, если у вас 25 записей?

person Jakub Konecki    schedule 14.12.2010
comment
Конечно, MyFunction() должна выполняться столько раз, сколько записей в таблице. Это не моя забота. Проблема в том, что сам оператор SQL (выберите MyFunction (TestId) из Test) ОТПРАВЛЯЕТСЯ на SQL-сервер 25 раз! Если вы посмотрите в профилировщик SQL и проверите, что происходит за выполнением этого оператора, вы поймете, о чем я говорю. - person Dmitry O; 14.12.2010
comment
@Dimitry - Очевидно, у меня нет ни вашего кода, ни вашей базы данных, поэтому я не могу просто «посмотреть в профилировщике SQL». Это может помочь, если вы опубликуете больше кода, особенно тот, который оценивает ваш запрос linq. - person Jakub Konecki; 14.12.2010
comment
Вам не нужна моя база данных или мой код, чтобы посмотреть на эту очень общую проблему. Просто создайте любую пользовательскую функцию, подключите ее к Linq to Entities и запустите любой запрос Linq, который использует эту функцию. Теперь посмотрите на профилировщик SQL, и вы увидите, что он работает с аномально большим количеством запросов (вместо ожидаемого 1 запроса). - person Dmitry O; 14.12.2010