Entity Framework 5 выполняет полное сканирование таблицы
-
13-12-2019 - |
Вопрос
У меня есть следующий код:
public List<anEntity> Get(int page, int pagesize, Func<anEntity, IComparable> orderby)
{
using (var ctx = new MyContext())
{
return ctx.anEntity.OrderBy(orderby).Skip(pagesize * page).Take(pagesize).ToList();
}
}
Когда я проверяю свой профиль базы данных (SqlServer 2012), я вижу ужасное полное сканирование таблицы без какого-либо предложения «TOP».
Интересная часть:
Если я сделаю что-то подобное, но указав конкретный порядок:
return ctx.anEntity.OrderBy(x => x.aField).Skip(pagesize * page).Take(pagesize).ToList();
В профиле есть красивый пункт «ТОП».
Я хотел бы избежать множества методов, по одному для каждой возможности «orderby».Любой намек будет очень признателен.
Решение
Это потому, что твой orderby
параметр — это функция, а не выражение.Невозможно преобразовать произвольную функцию в SQL, поэтому все ваши данные должны находиться на стороне клиента до вызова этой функции.
Измените тип параметра на Expression<Func<anEntity, T>>
, где T
это новый общий параметр, который вам следует добавить в свой Get
метод, и он будет работать так, как ожидалось.
Конечно, вы не сможете использовать собственный IComparable
, но обойти это невозможно:пользовательский код невозможно перевести в SQL.