Inquiridor
Compiled Query

Pergunta
-
Gostaria de fazer join entre duas Compiled Query, porém tenho erro de execução, alguem sabem alguma alteranativa?
public static readonly Func<DevcompyEntities, IQueryable<EstadoEntity>> Estado = CompiledQuery.Compile((DevcompyEntities db) => from e in db.EstadoEntity select e); public static readonly Func<DevcompyEntities, IQueryable<CidadeEntity>> Cidade = CompiledQuery.Compile((DevcompyEntities db) => from e in db.CidadeEntity select e); public static readonly Func<DevcompyEntities, IQueryable<CidadeEntity>> CidadeEstado = CompiledQuery.Compile((DevcompyEntities db) => from c in Cidade(db) join e in Estado(db) on c.EstadoId equals e.EstadoId select c); void Main() { //Estado(this).Dump(); //Cidade(this).Dump(); CidadeEstado(this).Dump(); } // Define other methods and classes here
Todas as Respostas
-
Olá Pablo,
Qual mensagem de erro vc esta recebendo?
[]s!
Fernando Henrique Inocêncio Borba Ferreira
Microsoft MVP - Data Platform Development
while(alive){ this.WriteCode(); }
Blog: http://ferhenriquef.com/
Twitter: @ferhenrique
Entity Framework - Brasil: https://www.facebook.com/EntityFrameworkBrasil -
-
Uma alternativa, mas não achei boa, seria não usar o CompiledQuery.Compile.
Seria uma solução, mas em casos de consultas mais caras para a Engine do EF teria uma perca de performance, pois em o Compiled Query o EF não faria chace dessas consultas, pelo menos foi o que consegui entender até agora sobre o Compiled Query.
-
Olá,
Realmente acredito que não irá funcionar.
Duas alternativas são:
1 - A sua terceira query não ser compilada, assim:
var query = from c in Cidade(db) join e in Estado(db) on c.EstadoId equals e.EstadoId select c; .
2 - Sua query compilada ser assim:
static readonly Func<DevcompyEntities, IQueryable<CidadeEntity>> CidadeEstado = CompiledQuery.Compile((DevcompyEntities db) => from c in db.CidadeEntity join e in db.EstadoEntity on c.EstadoId equals e.EstadoId select c); .
A construção de uma query compilada a partir de duas não é possível.
[]s!
Fernando Henrique Inocêncio Borba Ferreira
Microsoft MVP - Data Platform Development
while(alive){ this.WriteCode(); }
Blog: http://ferhenriquef.com/
Twitter: @ferhenrique
Entity Framework - Brasil: https://www.facebook.com/EntityFrameworkBrasil -
é que na realidade o que precisava mesmo era criar querys e poder reaproveitar elas conforme a necessidade.
porém pelo que andei estudando, se eu criar uma compiled query e utilizar ela num join com uma não compilada, eu perco a performance desta querya compilada, então a real necessidade de querys compiladas é somente na consulta que será chamada pela aplicação.
uma alternativa para o que estou tentando fazer seria o seguinte, mas ainda não testei a performance.
public static readonly Func<DevcompyEntities, IQueryable<EstadoEntity>> Estado = CompiledQuery.Compile((DevcompyEntities db) => from e in db.EstadoEntity select e); public static readonly Func<DevcompyEntities, IQueryable<CidadeEntity>> Cidade = CompiledQuery.Compile((DevcompyEntities db) => from e in db.CidadeEntity select e); public Func<DevcompyEntities, IQueryable<CidadeEstadoEntity>> CidadeEstado { get { DateTime now = DateTime.Now; var cidades = Cidade(this); var estados = Estado(this); Console.WriteLine(DateTime.Now - now); return CompiledQuery.Compile((DevcompyEntities db)=> from c in cidades join e in estados on c.EstadoId equals e.EstadoId select new CidadeEstadoEntity() { EstadoId = e.EstadoId, CidadeId = c.CidadeId, Cidade = c.Descricao, Estado = e.Descricao }); } } void Main() { //Estado(this).Dump(); //Cidade(this).Dump(); CidadeEstado(this).Dump(); } public class CidadeEstadoEntity { public int EstadoId {get;set;} public int CidadeId {get;set;} public string Cidade{get;set;} public string Estado{get;set;} }
fico no aguardo sobre uma análise desta alternativa que proponho para o referido problema em questão.
- Editado Pablotdv segunda-feira, 29 de outubro de 2012 11:02
-
Oi Pablo,
Tudo beleza?
Chegou a testar esta implementação?
O meu receio de trabalhar desta forma seja que vc execute três queries ao invés de uma. Quando vc executar cada uma das queries compiladas no seu join vc irá no banco de dados duas vezes, pois cada query precisa pegar seus resultados para o join, e então fazer o join entre os dados em memória. Isto é, vc vai acabar executando 3 consultas em uma única consulta, duas no banco de dados e uma em memória.
Acredito que a solução mais simples realmente seja criar cada query com sua devida estrutura, sem reaproveitar outras queries compiladas.
Ligue o trace do banco de dados, assim poderá ver se as duas consultas adicionais são executadas.
[]s!
Fernando Henrique Inocêncio Borba Ferreira
Microsoft MVP - Data Platform Development
while(alive){ this.WriteCode(); }
Blog: http://ferhenriquef.com/
Twitter: @ferhenrique
Entity Framework - Brasil: https://www.facebook.com/EntityFrameworkBrasil- Sugerido como Resposta AndreAlvesLimaModerator terça-feira, 30 de outubro de 2012 11:55
-
Fernando,
Acredito que não seja executada duas consultas, pois uso como retorno pras minhas querys um IQueryable e pelo que sei, o IQueryable só executa a consulta no banco quando é invocado algum método que precise dos dados do banco, como por exemplo um Count.
esta é a consulta gerada pelo LINQPad
SELECT [Extent1].[CidadeId] AS [CidadeId], [Extent2].[EstadoId] AS [EstadoId], [Extent1].[Descricao] AS [Descricao], [Extent2].[Descricao] AS [Descricao1] FROM [dbo].[Cidade] AS [Extent1] INNER JOIN [dbo].[Estado] AS [Extent2] ON [Extent1].[EstadoId] = [Extent2].[EstadoId]
para te dar mais informações sobre o que o trace do banco gera, vou precisar de mais uns dias, pois nunca usei este recurso do SQL Server
-
Olá Pablo,
Vc chegou a simular as queries compiladas no LINQPad?
Se quiser, me mande a base de dados e eu vejo o trace para vc.
Acredito que infelizmente o EF não seja esperto o suficiente para mestrar o select das duas consultas e gerar uma só =/
[]s!
Fernando Henrique Inocêncio Borba Ferreira
Microsoft MVP - Data Platform Development
while(alive){ this.WriteCode(); }
Blog: http://ferhenriquef.com/
Twitter: @ferhenrique
Entity Framework - Brasil: https://www.facebook.com/EntityFrameworkBrasil -