2010-03-28 8 views
3

Je voudrais reproduire l'instruction SQL suivante en C# LinqToSqlPour Sql Linq jointure externe gauche - filtrage des résultats nuls

SELECT TOP(10) Keywords.* 
FROM   Keywords 
LEFT OUTER JOIN IgnoreWords 
    ON Keywords.WordID = IgnoreWords.ID 
WHERE (DomainID = 16673) 
    AND (IgnoreWords.Name IS NULL) 
ORDER BY [Score] DESC 

Voici C# LINQ donne la bonne réponse. (? Une meilleure façon de le faire)
Mais je ne peux pas aider à penser que je manque quelque chose

var query = (from keyword in context.Keywords 
    join ignore in context.IgnoreWords 
     on keyword.WordID equals ignore.ID into ignored 
    from i in ignored.DefaultIfEmpty() 
    where i == null 
    where keyword.DomainID == ID 
    orderby keyword.Score descending 
    select keyword).Take(10); 

SQL produit ressemble à quelque chose comme ceci:

SELECT TOP (10) 
     [t0].[DomainID] 
    , [t0].[WordID] 
    , [t0].[Score] 
    , [t0].[Count] 
    FROM [dbo].[Keywords] AS [t0] 
    LEFT OUTER JOIN 
    ( SELECT 1 AS [test] 
      , [t1].[ID] 
     FROM [dbo].[IgnoreWords] AS [t1] 
    ) AS [t2] 
    ON [t0].[WordID] = [t2].[ID] 
WHERE ([t0].[DomainID] = 16673) 
    AND ([t2].[test] IS NULL) 
ORDER BY [t0].[Score] DESC 

Comment puis-je me débarrasser de cette sélection interne redondante? C'est un peu plus cher mais tout est utile!

+1

NOT IN' et NOT EXISTS' sont plus efficaces que 'LEFT JOIN/IS null' sur SQL Server: http://explainextended.com/2009/09/15/not-in-vs-not-exists-vs-left-join-is-null-sql-server/ –

+0

Avez-vous vérifié le plan de requête pour voir si ça fait une différence? – Gabe

+0

@gabe - Oui, il y a une différence mesurable –

Répondre

4

Je pense que vous pouvez faire quelque chose comme ça pour éliminer la jointure gauche et peut-être obtenir plus d'efficacité:

var query = (from keyword in context.Keywords 
      where keyword.DomainID == ID 
      && !(from i in context.IgnoreWords select i.ID).Contains(keyword.WordID) 
      orderby keyword.Score descending 
      select keyword) 
      .Take(10); 
+0

Oui c'est la réponse que je viens trouvé :) –

+0

Tant cette réponse et le code en question sont assez simple. Quelqu'un a-t-il un article qui publie des résultats de référence sur ces méthodes aux uns contre les autres? – RLH