O Entity Framework 5 efectuar full table scan
-
13-12-2019 - |
Pergunta
Eu tenho o seguinte código:
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();
}
}
Quando eu verificar meu banco de dados de perfil (SqlServer 2012) eu posso ver um horrível digitalização completa da tabela, sem qualquer "TOP" cláusula.
A parte interessante:
Se eu fizer algo de semelhante, mas a especificação de um concreto orderby:
return ctx.anEntity.OrderBy(x => x.aField).Skip(pagesize * page).Take(pagesize).ToList();
O perfil mostra um belo "TOP" cláusula.
Eu gostaria de evitar o lote de métodos, um para cada "orderby" possibilidade.Qualquer dica seria muito apreciada.
Solução
Isso porque o seu orderby
parâmetro é uma função ao invés de expressão.Não há nenhuma maneira de traduzir uma função arbitrária em SQL, para que todos os seus dados para estar no lado do cliente antes que a função é chamada.
Alterar o tipo de parâmetro para Expression<Func<anEntity, T>>
, onde T
é um novo parâmetro genérico que você deve adicionar à sua Get
o método, e ele vai funcionar como o esperado.
Claro, você não será capaz de usar um personalizado IComparable
, mas não há nenhuma maneira de contornar isso:código personalizado não pode ser traduzido em SQL.