LINQ中的条件连接

时间:2009-09-21 04:12:54

标签: c# .net linq-to-sql join conditional

我有父子表关系。在下面的示例中,Foo有一个FooID和一个可空的ParentFooID,它指向父记录。

Bar表始终链接到父记录。这是我用来获得结果的SQL。

Select * from Foo f
JOIN  Bar b
  ON b.FooID =  
     CASE 
       WHEN f.ParentFooID is null
         THEN f.FooID
       ELSE f.ParentFooID
     END

我在进入LINQ查询时遇到了一些麻烦。我想避免像以下一样交叉连接:

    var q = from f in Foo 
            from b in Bar 
            where  b.FooID == (f.ParentFooID ?? f.FooID)

干杯,

丹尼尔

3 个答案:

答案 0 :(得分:5)

您的具体示例是使用CASE回退到非空值,实际上只是COALESCE。在这种情况下,这有效:

var q = from f in dc.Foos
        join
        b in dc.Bars
        on
        (f.ParentFooID ?? f.FooID)
        equals
        b.FooID
        into grouped
        select grouped;

转化为:

SELECT ...
FROM [dbo].[Foo] AS [t0]
LEFT OUTER JOIN [dbo].[Bar] AS [t1]
ON (COALESCE([t0].[ParentFooID],[t0].[FooID])) = [t1].[FooID]
ORDER BY [t0].[FooID], [t1].[BarID]

键是COALESCE(case1, case2)上的左外连接,所以表达式转换器似乎明白了。

答案 1 :(得分:1)

不直接回答您的问题,但如果没有条件限制,原始查询不会更好地表达:

Select * 
from Foo f
JOIN Bar b ON b.FooID = f.FooID
Where f.ParentFooID is null
UNION ALL
Select * 
from Foo f
JOIN Bar b ON b.FooID = f.ParentFooID
Where f.ParentFooID is not null

在哪种情况下,LINQ表达式应该更容易?

答案 2 :(得分:0)

LINQ没有很好地映射一些复杂的场景;我建议加入case就是其中之一。重新做它作为一个交叉加入...有你的形象吗? (即from ... from ...(LINQ)与复杂join(TSQL)的后续SQL?在许多情况下,探查器可以从旧式方法中获得相同(或类似)的查询计划。