Por que o EF 4.1 não suporta consultas complexas e linq-sql?
Estou no processo de converter nosso aplicativo Web interno de Linq-To-Sql para EF CodeFirst a partir de um banco de dados existente. Ultimamente, tenho me irritado com as limitações do Linq-To-Sql, e ter que atualizar o edmx após atualizar uma tabela de banco de dados muito interligada finalmente me frustrou o suficiente para mudar para o EF.
No entanto, estou enfrentando várias situações em que o uso do linq com o Linq-To-Sql é mais poderoso que o mais recente Entity Framework, e estou me perguntando se alguém sabe o motivo disso. A maior parte disso parece lidar com transformações. Por exemplo, a consulta a seguir funciona em L2S, mas não em EF:
var client = (from c in _context.Clients
where c.id == id
select ClientViewModel.ConvertFromEntity(c)).First();
No L2S, isso recupera corretamente um cliente do banco de dados e o converte em umClientViewModel
, mas no EF essas exceções dizem que o Linq to Entities não reconhece o método (o que faz sentido como eu escrevi.
Para fazer isso funcionar na EF, tenho que mover oselect
após oFirst()
ligar
Outro exemplo é minha consulta para recuperar uma lista de clientes. Na minha consulta, eu a transformo em uma estrutura anônima para ser convertida emJSON
:
var clients = (from c in _context.Clients
orderby c.name ascending
select new
{
id = c.id,
name = c.name,
versionString = Utils.GetVersionString(c.ProdVersion),
versionName = c.ProdVersion.name,
date = c.prod_deploy_date.ToString()
})
.ToList();
Não é só o meuUtils.GetVersionString()
causa uma exceção de método não suportada no EF, oc.prod_deploy_date.ToString()
causa um também e é um simplesDateTime
. Como anteriormente, para corrigi-lo, tive que fazer minha transformação de seleção depois deToList()
.
context.TfsWorkItemTags.Where(x => x.TfsWorkItem == TfsWorkItemEntity).ToList()
lança uma exceção e, em vez disso, tenho que fazer
context.TfsWorkItemTags.Where(x => x.TfsWorkItem.id == tfsWorkItemEntity.id).ToList()
Edit 2: Queria adicionar outro problema que encontrei. Aparentemente, você não pode usar matrizes nas consultas do EF Linq, e isso provavelmente me incomoda mais do que qualquer coisa. Por exemplo, agora eu converto uma entidade que denota uma versão emint[4]
e tente consultá-lo. No Linq para Sql, usei a seguinte consulta:return context.ReleaseVersions.Where(x => x.major_version == ver[0] && x.minor_version == ver[1]
&& x.build_version == ver[2] && x.revision_version == ver[3])
.Count() > 0;
Isso falha com a seguinte exceção:
The LINQ expression node type 'ArrayIndex' is not supported in LINQ to Entities.
Edit 3: Encontrei outra instância da implementação incorreta do Linq da EF. A seguir, uma consulta que funciona no L2S, mas não no EF 4.1:
DateTime curDate = DateTime.Now.Date;
var reqs = _context.TestRequests.Where(x => DateTime.Now > (curDate + x.scheduled_time.Value)).ToList();
Isto lança umArgumentException
com a mensagemDbArithmeticExpression arguments must have a numeric common type.