2012-06-18 4 views
7

Ho la seguente query LINQ:Perché LINQ-to-Entities inserisce questa query in una sottoselezione?

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

che si traduce al seguente quando viene eseguito:

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] 

Ora sono abbastanza sicuro che la ragione v'è una sub-select è perché ho la query LINQ di base è circondata da() e quindi esegue .Distinct(), ma non ne so abbastanza su LINQ per essere sicuro di ciò. Se è davvero così, c'è un modo per ristrutturare/codificare la mia query in modo che non si verifichi una sotto-selezione?

So che probabilmente sembra che io sia solo un pignolo, ma sono solo curioso.

+0

È [tag: linq-to-sql], [tag: linq-to-entities] o [tag: linq-to-nhibernate]? –

+0

@DannyVarod linq-to-entities Credo che dal momento che sto usando EF4 sto interrogando un database Sybase. – Kittoes0124

+0

In tal caso, modificare il tag utilizzato e aggiornare di conseguenza il titolo della domanda. –

risposta

4

In questo sospetto che l'effettiva causa principale della sottoquery sia il costruttore di tipo anonimo. Poiché non si sta selezionando un'entità conosciuta, ma piuttosto un oggetto arbitrario costruito da altri valori di entità, il parser EF deve assicurarsi che possa produrre l'insieme esatto di campi, da una singola tabella, tabelle unite, campi calcolati, altro sottoquery, ecc. Il parser dell'albero dell'espressione è molto bravo a scrivere istruzioni SQL su query LINQ ogni volta che è possibile, ma non è onnisciente. Elabora le query in modo sistematico, che produrrà sempre risultati corretti (nel senso che ottieni ciò che hai chiesto), sebbene non sempre risultati ottimali.

Per quanto riguarda la riscrittura della query per eliminare la sotto-selezione, prima di tutto: non vedo un modo ovvio per farlo in modo da eliminare il tipo anonimo e produrre risultati corretti. Ancora più importante, però, I non darebbe fastidio allo. I moderni server SQL come Sybase sono molto intelligenti - spesso più intelligenti dello sviluppatore - e molto bravi a produrre un piano di query ottimale da una query. Oltre a questo, EF ama le sottoquery, perché sono ottimi modi per scrivere query complesse in modo automatico. Li trovi spesso anche quando la tua query LINQ non sembra usarli. Cercare di eliminarli tutti dalle tue domande diventerà rapidamente un esercizio di futilità.

+0

Grazie per la risposta eccellente e ben dettagliata. Volevo solo essere sicuro di non aver commesso errori evidenti. – Kittoes0124

4

Non mi preoccuperei affatto di questa particolare situazione. SQL Server (e molto probabilmente qualsiasi database aziendale) ottimizzerà comunque l'istruzione Select esterna. Io teorizzerei che il motivo per cui questa istruzione SQL è generata è perché questa è la dichiarazione più generica e riusabile. Dalla mia esperienza, questo succede sempre su Distinct().