2014-12-07 76 views
1

我试图将SQL query转换为Linq包含几个左外部联接,但我遇到了一个奇怪的情况。SQL到Linq查询与多个左外部联接

我的SQL的相关部分是:

SELECT * FROM dbo.SessionDetails as sd 
    left outer join dbo.VoipDetails as vd on vd.SessionIdTime = sd.SessionIdTime and vd.SessionIdSeq = sd.SessionIdSeq 
    left outer join dbo.Gateways as fgw on vd.FromGatewayId = fgw.GatewayId 

我Linq查询到目前为止是:

var query = from sd in dbo.SessionDetails 
    join vd in dbo.VoipDetails on new { sd.SessionIdTime, sd.SessionIdSeq } equals new { vd.SessionIdTime, vd.SessionIdSeq } into sdvd 
    from v in sdvd.DefaultIfEmpty() 
     join fgw in dbo.Gateways on vd.FromGatewayId equals fgw.GatewayId into sdgw 
     from g in sdvd.DefaultIfEmpty() 
      select sd; 

我得到一个错误标记上vd.FromGatewayId告诉我,The name 'vd' is not in scope on the left side of 'equals'. Consider swapping the expressions on either side of 'equals'.
然而,如果我与gw.GatewayId交换双方,那么我得到相同的错误消息vdgw。 有人可以在这里建议正确的语法吗? 请记住,我有几个左连接添加后,我得到的基本语法。

回答

2

我相信问题是您试图访问查询中没有范围的值。我相信这样做的原因是,你指定关系,然后将这些值分配给一个名为sdvd的集合,此时你无法访问vd。也就是说,通过这样做,您可以执行from v in sdvd.DefaultIfEmpty(),以便您可以访问sdvd中的行,这些行与您认为的vd所持有的值相同。您应该可以使用v而不是vd。我不得不嘲笑一些东西来测试,所以我无法确切地测试这个查询,但应该运行以下内容。

var query = from sd in dbo.SessionDetails 
    join vd in dbo.VoipDetails on new { sd.SessionIdTime, sd.SessionIdSeq } equals new { vd.SessionIdTime, vd.SessionIdSeq } into sdvd 
    from v in sdvd.DefaultIfEmpty() 
     join fgw in dbo.Gateways on v.FromGatewayId equals fgw.GatewayId into sdgw 
     from g in sdvd.DefaultIfEmpty() 
      select sd; 

编辑2014年12月8日

为了看到LINQ语句如何转换为SQL,我建议你安装https://www.linqpad.net/。您可以建立连接并测试您的查询,并在结果视图中查看sql。

因为我没有这个问题的数据结构,所以很难。这就是说我嘲笑了一句:

from sd in Employees 
    join vd in TimeEntries on new { sd.EmployeeID } equals new { vd.EmployeeID } into sdvd 
    from v in sdvd.DefaultIfEmpty() 
     join fgw in EmployeeGroupDetails on v.EmployeeID equals fgw.EmployeeID into sdgw 
     from g in sdgw.DefaultIfEmpty() 
      select sd 

这产生了:

SELECT [t0].* 
FROM [Employee] AS [t0] 
LEFT OUTER JOIN [TimeEntry] AS [t1] ON [t0].[EmployeeID] = [t1].[EmployeeID] 
LEFT OUTER JOIN [EmployeeGroupDetail] AS [t2] ON [t1].[EmployeeID] = [t2].[EmployeeID] 

它回来与正确的连接。

+0

我很可能会误解,但为了继续做左外连接,不应该将'v.FromGatewayId'等于fgw.GatewayId'从sdgw.DefaultIfEmpty()'中的g放入sdgw中,而不是'再次使用sdvd.DefaultIfEmpty()? – Black 2014-12-07 23:15:06