2010-03-28 50 views
3

我想複製下面的SQL到C#LinqToSqlLINQ to SQL的LEFT OUTER JOIN - 過濾空結果

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

'不IN'和'NOT EXISTS'更有效率比'LEFT JOIN/IS NULL'上SQL Server:http://explainextended.com/2009/09/15/not-in-vs-not-exists-vs-left-join-is-null-sql-server/ – 2010-03-28 05:33:47

+0

您是否檢查了查詢計劃以查看如果它有所作爲? – Gabe 2010-03-28 05:38:21

+0

@gabe - 是的,有一個可測量的差異 – 2010-03-28 05:39:16

回答

4

我認爲你可以做這樣的事情,以消除左聯接,也許獲得更多的效率:

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

是的,這是我的答案只是發現:) – 2010-03-28 05:44:54

+0

這個答案和有問題的代碼都非常簡單。任何人都有一篇文章將這些方法的基準測試結果與其他方法進行比較? – RLH 2015-12-30 20:10:32