2010-11-12 88 views
1

我有以下SQL查询,我想改写成LINQ:需要帮助的LINQ查询左联接和多领域

SELECT gp.Name 
, r.DateOfRace 
, ISNULL(SUM(rr.Points), 0) AS Points 
FROM Races r 
INNER JOIN GrandPrix gp 
ON r.GrandPrixId = gp.GrandPrixId 
LEFT JOIN Predictions p 
ON p.RaceId = r.RaceId 
AND p.AdditionalUserInformationId = 2 
LEFT JOIN RaceResults rr 
ON p.DriverId = rr.DriverId 
AND p.FinishPosition = rr.FinishPosition 
AND p.RaceId = rr.RaceId 
WHERE r.Season = 2010 
GROUP BY gp.Name 
, p.RaceId 
, r.DateOfRace 

这是多少我得到,当它仍然在工作:

from races in Races 
join grandprix in GrandPrixes 
on races.GrandPrixId equals grandprix.GrandPrixId 
from Predictions in Predictions.Where(v => v.RaceId == races.RaceId).DefaultIfEmpty() 
select new 
{ 
DateOfRace = races.DateOfRace, 
GrandPrix = grandprix.Name, 
} 

当我走得更远时,事情就出错了 - 例如我无法获得AND p.AdditionalUserInformationId = 2的权利。

我希望有人能帮忙!

回答

3

你可以做到以下几点:

join p in Predictions 
    on new { p.RaceId, p.AdditionalUserInformationId } = 
     new { r.RaceId, AdditionalUserInformationId = 2 } into ps 
from p in ps.DefaultIfEmpty() 
join rr in RaceResults 
    on new { p.DriverId, p.RaceId, p.FinishPosition } = 
     new { rr.DriverId, rr.RaceId, rr.FinishPosition } into rrs 
from rr in rrs.DefaultIfEmpty() 

您使用C#在结构上比较匿名类型的能力。两个匿名类型使用相同的属性创建,这使得它们成为同一类的实例。这些实例可以进行比较。

+0

谢谢(Dank je wel :-))罗纳德,这帮了我很多。 尽管最后一件事 - 这些连接产生内连接而不是左连接。我在文章中使用的语法使用了实际做到这一点的.Where()方法。有了这个版本,这是不适用了,所以......有一个简单的解决方案? – Benjamin 2010-11-13 09:51:45

+0

Graag gedaan :)我已更新我的答案,以便它使用两个左外连接。 – 2010-11-15 12:35:44

+0

Da的幻想! (太棒了!)你在这里做了一个快乐的人罗纳德! – Benjamin 2010-11-15 15:20:29

1
join grandprix in GrandPrixes 
on new {races.GrandPrixId, p.AdditionalUserInformationId} equals new {grandprix.GrandPrixId,2} 
+0

这不会编译。您必须以匿名类型为每个属性命名。 – 2010-11-12 07:18:26

+0

你是对的.. – 2010-11-12 07:19:28