Linq To Sql 左外连接 - 过滤空结果

Posted

技术标签:

【中文标题】Linq To Sql 左外连接 - 过滤空结果【英文标题】:Linq To Sql Left outer join - filtering null results 【发布时间】:2011-02-01 16:26:58 【问题描述】:

我想将以下 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

如何摆脱这种多余的内部选择? 它只是稍微贵一点,但每一点都有帮助!

【问题讨论】:

NOT INNOT EXISTS 在 SQL Server 上比 LEFT JOIN/IS NULL 更高效:explainextended.com/2009/09/15/… 您检查过查询计划是否有所作为? @gabe - 是的,存在可衡量的差异 阅读这篇文章。似乎高度相关:introducinglinq.com/blogs/marcorusso/archive/2008/01/14/… 【参考方案1】:

我认为您可以执行以下操作来消除左连接并提高效率:

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

【讨论】:

是的,这就是我刚刚找到的答案:) 这个答案和有问题的代码都非常简单。任何人都有一篇文章将这些基准结果发布到方法与其他方法之间?

以上是关于Linq To Sql 左外连接 - 过滤空结果的主要内容,如果未能解决你的问题,请参考以下文章

Linq to Sql:多个左外连接

Linq to SQL 使用 Lambda 语法进行左外连接并在 2 列上连接(复合连接键)

在 Linq 中使用左外连接

LINQ to SQL 执行联合和左外连接

Linq to Entity 具有多个左外连接

如何在 LINQ 中使用左外连接进行 SQL 查询?