/ / Por que o LINQ-to-Entities coloca essa consulta em uma sub-seleção? - c #, linq, linq para entidades, sybase

Por que o LINQ to Entities coloca essa consulta em uma sub-seleção? - c #, linq, linq para entidades, sybase

Eu tenho a seguinte consulta LINQ:

var queryGroups = (from p in db.cl_contact_event
select new Groups { inputFileName = p.input_file_name }).Distinct();

O que se traduz no seguinte quando executado:

SELECT
[Distinct1].[C1] AS [C1],
[Distinct1].[input_file_name] AS [input_file_name]
FROM ( SELECT DISTINCT
[Extent1].[input_file_name] AS [input_file_name],
1 AS [C1]
FROM [mel].[cl_contact_event] AS [Extent1]
)  AS [Distinct1]

Agora tenho certeza de que a razão de existirA sub-seleção é porque eu tenho a consulta LINQ base cercada por () e, em seguida, realizo .Distinct (), mas não sei o suficiente sobre o LINQ para ter certeza disso. Se esse for realmente o caso, existe uma maneira de reestruturar / codifica minha consulta para que uma sub-seleção não ocorra?

Eu sei que provavelmente parece que estou escolhendo aqui, mas estou apenas curioso.

Respostas:

4 para resposta № 1

Nisso, suspeito que a causa raiz real dea subconsulta é o construtor do tipo anônimo. Como você não está selecionando uma entidade conhecida, mas um objeto arbitrário construído a partir de outros valores de entidade, o analisador EF precisa garantir que ele possa produzir o conjunto exato de campos - seja de uma única tabela, tabelas unidas, campos calculados, outros subconsultas etc. O analisador de árvore de expressão é muito bom em escrever instruções SQL a partir de consultas LINQ sempre que possível, mas não é onisciente. Ele processa as consultas de maneira sistemática, que sempre produzirá resultados corretos (no sentido que você obtém o que pediu), embora nem sempre os melhores resultados.

Quanto a reescrever a consulta para eliminar a sub-seleção, primeiro: não vejo uma maneira óbvia de fazer isso que elimine o tipo anônimo e produza resultados corretos. Mais importante, porém, eu não incomodaria. Servidores SQL modernos como o Sybase são muito inteligentes- geralmente mais esperto que o desenvolvedor - e muito bom em produzir um plano de consulta ideal a partir de uma consulta. Além disso, o EF adora subconsultas, porque são maneiras muito boas de escrever consultas complexas de maneira automatizada. Você geralmente os encontra mesmo quando sua consulta LINQ não apareceu, use-os. Tentar eliminar todos eles de suas consultas rapidamente se tornará um exercício de futilidade.


4 para resposta № 2

Eu não me preocuparia com esta situação em particularem absoluto. O SQL Server (e provavelmente qualquer banco de dados corporativo) otimizará a instrução Select externa de qualquer maneira. Eu teorizaria que a razão pela qual essa instrução SQL é gerada é porque esta é a instrução mais genérica e reutilizável. Da minha experiência, isso sempre acontece em Distinct().