2014-12-07 103 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