2010-06-16 147 views
2

我試圖將SQL連接轉換爲LINQ。我需要一些幫助來獲得LINQ中的嵌套連接。LINQ嵌套連接

這是我的SQL查詢,我已經把它剪短只是爲了顯示嵌套連接在SQL:

select distinct 
txtTaskStatus as TaskStatusDescription, 
    txtempfirstname+ ' ' + txtemplastname as RaisedByEmployeeName, 
    txtTaskPriorityDescription as TaskPriorityDescription, 
    dtmtaskcreated as itemDateTime, 
    dbo.tblTask.lngtaskid as TaskID, 
    dbo.tblTask.dtmtaskcreated as CreatedDateTime, 
    convert(varchar(512), dbo.tblTask.txttaskdescription) as ProblemStatement, 
    dbo.tblTask.lngtaskmessageid, 
    dbo.tblMessage.lngmessageid as MessageID, 
    case when isnull(dbo.tblMessage.txtmessagesubject,'') <> '' then txtmessagesubject else left(txtmessagedescription,50) end as MessageSubject, 
    dbo.tblMessage.txtmessagedescription as MessageDescription, 
    case when dbo.tblMessage.dtmmessagecreated is not null then dbo.tblMessage.dtmmessagecreated else CAST(FLOOR(CAST(dtmtaskcreated AS DECIMAL(12, 5))) AS DATETIME) end as MessageCreatedDateTime 

FROM 
dbo.tblAction RIGHT OUTER JOIN dbo.tblTask ON dbo.tblAction.lngactiontaskid = dbo.tblTask.lngtaskid 
LEFT OUTER JOIN dbo.tblMessage ON dbo.tblTask.lngtaskmessageid = dbo.tblMessage.lngmessageid 
LEFT OUTER JOIN dbo.tblTaskCommentRecipient 
    RIGHT OUTER JOIN dbo.tblTaskComment ON dbo.tblTaskCommentRecipient.lngTaskCommentID = dbo.tblTaskComment.lngTaskCommentID 
    ON dbo.tblTask.lngtaskid = dbo.tblTaskComment.lngTaskCommentTaskId 
+0

這是否SQL查詢的實際工作?如果是這樣,你使用什麼樣的SQL? – 2010-06-16 05:05:59

+0

是的,它的確如此。如果你願意,我可以過去整個查詢。基本上我正在尋找這樣做的linq語法。 – ace 2010-06-16 05:14:19

+0

請發佈整個查詢。它可能很容易理解 – anishMarokey 2010-06-16 05:18:35

回答

6

一個更豐富的SQL程序員不入的方式。爲了清晰起見,他們會嚴格使用左連接(因爲存在嚴格的左連接解決方​​案)。

我解開這些連接產生一個層次:

Task 
    Action 
    Message 
    TaskComment 
    TaskCommentRecipient 

隨着在LINQ to SQL設計創建的關聯,就可以到達層次結構的這些層次:

//note: these aren't outer joins 
from t in db.Tasks 
let actions = t.Actions 
let message = t.Messages 
let comments = t.TaskComments 
from c in comments 
let recipients = c.TaskCommentRecipients 

DefaultIfEmpty產生集合爲空時的默認元素。由於這些是數據庫行,因此默認元素是空行。這是左連接的行爲。

query = 
(
    from t in db.Tasks 
    from a in t.Actions.DefaultIfEmpty() 
    from m in t.Messages.DefaultIfEmpty() 
    from c in t.Comments.DefaultIfEmpty() 
    from r in c.Recipients.DefaultIfEmpty() 
    select new Result() 
    { 
    TaskStatus = ??? 
    ... 
    } 
).Distinct(); 

旁白:經過一堆加入是一個柺杖調用是不同的。 #1看看你能否沒有它。 #2如果不是,請查看是否可以消除導致您必須調用它的任何不良數據。 #3如果不是,請在比整個查詢更小的範圍內調用Distinct。

希望這會有所幫助。

+0

感謝大衛如此清楚地解釋它。 – ace 2010-06-16 21:47:51

0
SELECT [t0].[OrderID], [t0].[CustomerID], [t0].[EmployeeID], [t0].[OrderDate], [t0].[RequiredDate], [t0].[ShippedDate], [t0].[ShipVia], [t0].[Freight], [t0].[ShipName], [t0].[ShipAddress], [t0].[ShipCity], [t0].[ShipRegion], [t0].[ShipPostalCode], [t0].[ShipCountry] 
FROM [Orders] AS [t0] 
LEFT OUTER JOIN ([Order Details] AS [t1] 
    INNER JOIN [Products] AS [t2] ON [t1].[ProductID] = [t2].[ProductID]) ON [t0].[OrderID] = [t1].[OrderID] 

可以寫爲

from o in Orders 
join od in (
    from od in OrderDetails join p in Products on od.ProductID equals p.ProductID select od) 
    on o.OrderID equals od.OrderID into ood from od in ood.DefaultIfEmpty() 
select o