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 № 1Nisso, 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()
.