具有多个左外连接的 SQL 到 Linq 查询
本文关键字:SQL Linq 查询 连接 | 更新日期: 2023-09-27 18:33:20
我正在尝试将SQL query
转换为包含多个左外连接的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
交换了一边,那么我会收到相同的错误消息,vd
和gw
。有人可以在这里建议正确的语法吗?请记住,在我掌握基本语法后,我还需要添加几个左连接。
我相信问题是您正在尝试访问查询中没有范围的值。 我相信这样做的原因是您指定了关系船,然后将这些值分配给名为 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/08
为了了解 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]
它确实返回了正确的连接。