none
Query SQL Gerada pelo Entity Framework 4 muito ruim RRS feed

  • Pergunta

  • Percebi que o EF4 funciona até muito bem, gerando inner joins e etc, porém, quando uso LINQ To EF, e uso uma simples cláusula 'WHERE', ele gera subselects bizarros. Como fazer o EF gerar querys mais 'amigáveis'  ?

    Exemplo:

    SEM o WHERE no linq:

    SELECT TOP (12) 
    [Extent1].[IDItemPost] AS [IDItemPost], 
    [Extent1].[IDItemArquivoIcone] AS [IDItemArquivoIcone], 
    [Project1].[Ativo] AS [Ativo1]
    
    FROM  [dbo].[ItemPost] AS [Extent1]
    INNER JOIN [dbo].[Publico] AS [Extent2] ON [Extent1].[IDPublico] = [Extent2].[IDPublico]
    LEFT OUTER JOIN [dbo].[Publico] AS [Extent3] ON [Extent1].[IDPublico] = [Extent3].[IDPublico]
    ORDER BY [Extent1].[DataCadastro] DESC
    
    


    COM o WHERE no Linq:

    SELECT TOP (12) 
    [Project1].[IDItemPost] AS [IDItemPost], 
    [Project1].[IDItemArquivoIcone] AS [IDItemArquivoIcone], 
    [Project1].[Ativo] AS [Ativo1]
    
    FROM ( SELECT 
    	[Extent1].[IDItemPost] AS [IDItemPost], 
    	[Extent1].[IDItemArquivoIcone] AS [IDItemArquivoIcone], 
    	[Extent3].[Ativo] AS [Ativo1]
    	FROM  [dbo].[ItemPost] AS [Extent1]
    	INNER JOIN [dbo].[Publico] AS [Extent2] ON [Extent1].[IDPublico] = [Extent2].[IDPublico]
    	LEFT OUTER JOIN [dbo].[Publico] AS [Extent3] ON [Extent1].[IDPublico] = [Extent3].[IDPublico]
    	WHERE [Extent1].[Ativo] = @p__linq__0
    ) AS [Project1]
    ORDER BY [Project1].[DataCadastro] DESC
    


    quinta-feira, 25 de agosto de 2011 14:33

Respostas

  • PcClaro, boa tarde

    so pra deixar uma coisa clara, isto:

    SELECT TOP (12) 
    [Project1].[IDItemPost] AS [IDItemPost], 
    [Project1].[IDItemArquivoIcone] AS [IDItemArquivoIcone], 
    [Project1].[Ativo] AS [Ativo1]
    
    FROM ( SELECT 
    	[Extent1].[IDItemPost] AS [IDItemPost], 
    	[Extent1].[IDItemArquivoIcone] AS [IDItemArquivoIcone], 
    	[Extent3].[Ativo] AS [Ativo1]
    	FROM  [dbo].[ItemPost] AS [Extent1]
    	INNER JOIN [dbo].[Publico] AS [Extent2] ON [Extent1].[IDPublico] = [Extent2].[IDPublico]
    	LEFT OUTER JOIN [dbo].[Publico] AS [Extent3] ON [Extent1].[IDPublico] = [Extent3].[IDPublico]
    	WHERE [Extent1].[Ativo] = @p__linq__0
    ) AS [Project1]
    ORDER BY [Project1].[DataCadastro] DESC
    
    

    não é um subselect e sim uma Consulta Derivada, uma forma de relizar filtros e modificações de dados em uma tabela montada em tempo de execução dentro do mesmo resultSet http://imasters.com.br/artigo/13043/sql_server/implementando_tabelas_derivadas_no_sql_server/

    em nada isto irá interferir na perfomance do seu Sql Server.


    Olavo Oliveira Neto
    http://olavooneto.wordpress.com
    Se for útil marque como resposta e faça um Developer feliz :)
    quinta-feira, 8 de setembro de 2011 15:56
    Moderador

Todas as Respostas

  • Como está seu linq posta o code
    Não esqueça de usar o componente </> na barra para posta seu código. Microsoft MCPD,MCTS,MCC
    quinta-feira, 25 de agosto de 2011 15:00
  • Olá Pcclaro,

    Dei uma pesquisada e achei o seguinte link: http://msdn.microsoft.com/en-us/library/cc853327.aspx

    Procure pelo tópico Query Complexity.

     

    Nesse link é dito que joins complexos ou query complexas podem causar este problema.

    Nestes casos é indicado fazer o mapeamento para stored procedure ou funções que retornam tabelas.

     

    []s!


    Fernando Henrique Inocêncio Borba Ferreira
    while(alive){ this.WriteCode(); }
    Blog: http://ferhenriquef.wordpress.com/
    Twitter: @ferhenrique
    quinta-feira, 25 de agosto de 2011 16:53
    Moderador
  • Seilor, meu linq está assim:

     

     

    from e in c.ItemPost
    where e.Ativo.Equals(ativo) 
    orderby e.DataCadastro descending
    
    	select new VOItemPost
    	{
    	IDItemPost = e.IDItemPost,
    	IDItemArquivoIcone = e.IDItemArquivoIcone,
    									
    	Publico = new VOPublico
    	{
    	IDPublico = e.Publico.IDPublico,
    	NomePublico = e.Publico.NomePublico,
    	DataCadastro = e.Publico.DataCadastro,
    	Ativo = e.Publico.Ativo
    	},
    									
    DataCadastro = e.DataCadastro,
    Ativo = e.Ativo
    }).Take(12);
    
    


    quinta-feira, 25 de agosto de 2011 17:06
  • Pela lógica do seu linq o sql que gerou está correto :)
    Não esqueça de usar o componente </> na barra para posta seu código. Microsoft MCPD,MCTS,MCC
    sexta-feira, 26 de agosto de 2011 12:07
  • mas qual a lógica de gerar um subselect apenas por usar o 'WHERE' ?
    sexta-feira, 26 de agosto de 2011 13:17
  • PCClaro,

    O problema não está na clausula Where, e sim no acesso que vc faz ao atributo chamado Publico.

    	IDPublico = e.Publico.IDPublico,
    	NomePublico = e.Publico.NomePublico,
    	DataCadastro = e.Publico.DataCadastro,
    	Ativo = e.Publico.Ativo
    

    []s!


    Fernando Henrique Inocêncio Borba Ferreira
    while(alive){ this.WriteCode(); }
    Blog: http://ferhenriquef.wordpress.com/
    Twitter: @ferhenrique
    sexta-feira, 26 de agosto de 2011 13:38
    Moderador
  • Fernando, 

    Fiz o teste só para confirmar, mas mesmo sem o 'Publico', continua a mesma coisa, reforçando que o problema está no 'WHERE'.. muito estranho esse sql gerado, creio que posso ter problemas quando trabalhar com muitos dados.

    domingo, 28 de agosto de 2011 04:12
  • Olá PcClaro,

    O que vc achar de utilizar nesse caso procedures no Entity Framework?

    Olhe esse poste do meu amigo Nelson Borges: http://nelsonborges.wordpress.com/2009/12/05/entity-framework-%E2%80%93-usando-stored-procedures/

     

    []s!


    Fernando Henrique Inocêncio Borba Ferreira
    while(alive){ this.WriteCode(); }
    Blog: http://ferhenriquef.wordpress.com/
    Twitter: @ferhenrique
    quarta-feira, 31 de agosto de 2011 14:28
    Moderador
  • PcClaro, boa tarde

    so pra deixar uma coisa clara, isto:

    SELECT TOP (12) 
    [Project1].[IDItemPost] AS [IDItemPost], 
    [Project1].[IDItemArquivoIcone] AS [IDItemArquivoIcone], 
    [Project1].[Ativo] AS [Ativo1]
    
    FROM ( SELECT 
    	[Extent1].[IDItemPost] AS [IDItemPost], 
    	[Extent1].[IDItemArquivoIcone] AS [IDItemArquivoIcone], 
    	[Extent3].[Ativo] AS [Ativo1]
    	FROM  [dbo].[ItemPost] AS [Extent1]
    	INNER JOIN [dbo].[Publico] AS [Extent2] ON [Extent1].[IDPublico] = [Extent2].[IDPublico]
    	LEFT OUTER JOIN [dbo].[Publico] AS [Extent3] ON [Extent1].[IDPublico] = [Extent3].[IDPublico]
    	WHERE [Extent1].[Ativo] = @p__linq__0
    ) AS [Project1]
    ORDER BY [Project1].[DataCadastro] DESC
    
    

    não é um subselect e sim uma Consulta Derivada, uma forma de relizar filtros e modificações de dados em uma tabela montada em tempo de execução dentro do mesmo resultSet http://imasters.com.br/artigo/13043/sql_server/implementando_tabelas_derivadas_no_sql_server/

    em nada isto irá interferir na perfomance do seu Sql Server.


    Olavo Oliveira Neto
    http://olavooneto.wordpress.com
    Se for útil marque como resposta e faça um Developer feliz :)
    quinta-feira, 8 de setembro de 2011 15:56
    Moderador