我试图将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
收到相同的错误消息。
有人可以在这里建议正确的语法吗?
请记住,在我获得基本语法后,我还要添加几个左连接。
答案 0 :(得分: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;
EDIT 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
这个YIELDS:
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]
它确实以合适的连接回来。