Linq To Sql Левое внешнее соединение - фильтрация нулевых результатов - PullRequest
3 голосов
/ 28 марта 2010

Я хотел бы воспроизвести следующий SQL в C # LinqToSql

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

Следующий ответ C # Linq дает правильный ответ.
Но я не могу не думать, что что-то упустил (лучший способ сделать это?)

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 выглядит примерно так:

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

Как мне избавиться от этого лишнего внутреннего выделения? Это только немного дороже, но каждый помогает!

1 Ответ

4 голосов
/ 28 марта 2010

Я думаю, что вы можете сделать что-то подобное, чтобы устранить левое соединение и, возможно, получить большую эффективность:

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); 
...