Принудительная параметризация порядка Entity Framework

Я использую что-то похожее на DynamicLinq, чтобы можно было упорядочить результаты Entity Framework по строке, соответствующей имени свойства. Однако кажется, что всякий раз, когда свойство сортировки изменяется, кешированный SQL не используется, а вместо него создается новый оператор. Я ищу способ заставить Entity Framework использовать параметр SQL для предложения ORDER BY в генерируемых им операторах SQL.

Мне удалось преодолеть аналогичную проблему с помощью методов .Skip () и .Take (). Таким образом, соответствующие SELECT TOP N и WHERE ROW_NUMBER> M правильно параметризованы в выводе SQL.

Есть ли способ получить вывод SQL для использования предложения ORDER BY, которое выглядит примерно так:

ORDER BY [Foo].[@p__linq__24]

С точки зрения SQL это должно быть возможно.


person user653649    schedule 05.06.2014    source источник
comment
поправьте меня, если я ошибаюсь, но, как вы уже сказали, использование параметра там недопустимо.   -  person hometoast    schedule 05.06.2014
comment
Как вам это удалось с Skip и Take?   -  person Ben Aaronson    schedule 05.06.2014
comment
@hometoast ДОЛЖЕН быть возможен сделать это в SQL с помощью sp_executesql и динамического оператора SQL, именно так работает Entity Framework.   -  person user653649    schedule 05.06.2014
comment
спасибо @ user653649, я не подумал sp_executesql   -  person hometoast    schedule 05.06.2014


Ответы (1)


SQL Server не принимает параметры для ORDER BY.

Но, помимо этой детали, более важной является следующая: когда запрос будет выполняться, SQL-сервер создает оптимальный план выполнения запроса. При этом он решает, какие индексы использовать, как фильтруются строки, как объединяются таблицы и так далее. И изменение порядка результатов не настолько тривиально, чтобы ожидать, что предыдущий план выполнения все еще действителен (например, он может решить использовать другой индекс).

Другими словами, план выполнения используется повторно, только если изменения в запросе тривиальны (например, изменение значения фильтра). И даже в этом случае, в зависимости от статистики и избирательности значения фильтрации, он может решить сделать это по-другому. Например, представьте битовый столбец, содержащий 999 строк со значением 0 и 1 столбец со значением 1. Если статистика обновлена ​​правильно, SQL-сервер знает, что фильтрация по значению 1 является оптимальной для этого индекса (чрезвычайно избирательной), а фильтрация по 0 бессмысленно (почти неизбирательно).

Не беспокойтесь об этом, если вы не сталкиваетесь с крайними случаями, когда вам действительно нужна оптимизация.

Вы можете сделать свои собственные тесты, проверяя «Показать план выполнения запроса» в SSMS и глядя на план выполнения (настоящий, а не стимулированный ... Я не знаю точной формулировки на английском языке, у меня есть локализованная SSMS ).

person JotaBe    schedule 06.06.2014
comment
Я не пытаюсь оптимизировать план SQL, а скорее заставляю Entity Framework использовать один и тот же оператор SQL для запроса независимо от порядка по свойству. Entity Framework использует параметризованные динамические операторы SQL для выполнения запросов. Это означает, что элементы в предложениях where являются параметрами, переданными в оператор sql. Эти операторы кэшируются. Таким образом, не нужно каждый раз компилировать все дерево выражений в sql. Для сложных запросов это огромный ускоритель производительности. Я ищу способ параметризации предложения order by таким же образом, как и предложение where. - person user653649; 06.06.2014
comment
Даже если то, что вы хотите сделать, находится на стороне EF, упорядочить по параметрам невозможно. Вы измерили прирост производительности или просто воображаете это? Не стоит беспокоиться о производительности, если только не ясно, что существует серьезная проблема с производительностью. Вам может быть интересно прочитать эту обширную статью об оптимизации EF: msdn.microsoft.com/en -US / data / hh949853, специально 3.2.2 - person JotaBe; 06.06.2014