2016-02-05 78 views
1

我有三個層次的表「董事」,「經理」和「領導者」與一個在它們之間一對多的關係。LINQ查詢的outerjoining家長和孩子(嵌套)表

我想帶所有的董事,管理人員和領導者的行分別與子女的關係一起。(也許LeftOuterJoin)

例如董事表有

DirectorID DirectorName

 1   Director1 

經理

經理ID經理ID經理姓名

1    1     Manager 1 
    2    1     Manager 2 

領導

領導者ID經理ID負責人姓名

1     1    Leader 1 
    2     1    Leader 2 

我想查詢返回

DIRID DirectorName MGRID ManagerName LdrID LeaderName

1 Director1
1 Director1 1經理1
1 Director1 1 Manager1 1 Leader1
1 Director1 1 Manager1 2 Leader1
1 Director1 2 Manager2

我LINQ查詢只導致3行

DIRID DirectorName MGRID ManagerName LdrID LeaderName

1 Director1 1 Manager1 1 Leader1
1 Director1 1 Manager1 2 Leader1
1 Director1 2 Manager2

   var query = from d in db.Directors 
         join m in db.Managers on d.DirectorID equals m.DirectorID into directorMgrGroup 
         from dmgr in directorMgrGroup.DefaultIfEmpty() 
         join l in db.Leaders on dmgr.ManagerID equals l.ManagerID into mgrLeaderGroup 
         from mlgr in mgrLeaderGroup.DefaultIfEmpty() 

感覺就像一個小的調整。只是不能把它做對。誰能幫幫我嗎?謝謝。

+0

請註明'select'條款。另外預期的結果類型是什麼?'IQueryable <匿名類型>'或者可以是'IEnumerable <匿名類型>'?我在問,因爲連接不是問題,但樣本輸出不能用LINQ to Entities生成,但最終可以用LINQ to Objects生成。 –

+0

謝謝。我錯誤地忘了在上面的sql中添加它。但我在我的linq查詢中有一個select {}。 – lama

回答

2

感覺就像一個小的調整,

好了,不究竟。在SQL結果格式是由所謂的ROLLUP查詢未通過LINQ原生支持生產。GroupJoin將收集所需的信息,但它壓扁你想要的是挺難的,你可能會看到下面的方式(串聯組燎項目陣列的組合加入羣組)。檢查出來:

var query = 
db.Directors.GroupJoin(db.Managers, director => director.DirectorId, manager => manager.DirectorId, (director, managerGroup) => new 
{ 
    Id = director.DirectorID, 
    Name = director.DirectorName, 
    Managers = managerGroup.GroupJoin(db.Leaders, manager => manager.ManagerId, leader => leader.ManagerID, (manager, leaderGroup) => new 
    { 
     Id = manager.ManagerID, 
     Name = manager.ManagerName, 
     Leaders = leaderGroup.Select(leader => new 
     { 
      Id = leader.LeaderID, 
      Name = leader.LeaderName 
     }) 
    }) 
}) 
.SelectMany(director => 
    new[] { new 
    { 
     DirID = director.Id, DirectorName = director.Name, 
     MgrID = (int?)null, ManagerName = (string)null, 
     LdrID = (int?)null, LeaderName = (string)null 
    } } 
    .Concat(director.Managers.SelectMany(manager => 
     new[] { new 
     { 
      DirID = director.Id, DirectorName = director.Name, 
      MgrID = (int?)manager.Id, ManagerName = manager.Name, 
      LdrID = (int?)null, LeaderName = (string)null 
     } } 
     .Concat(manager.Leaders.Select(leader => new 
     { 
      DirID = director.Id, DirectorName = director.Name, 
      MgrID = (int?)manager.Id, ManagerName = manager.Name, 
      LdrID = (int?)leader.Id, LeaderName = leader.Name 
     })) 
    )) 
); 
+0

確實很複雜。我使它適用於我的情況。但我仍然圍繞着邏輯進行思考。感謝您的幫助。 – lama

0

我建議你寫一個SQL查詢,把它變成一個SQL視圖以及其對應爲EF實體。你會得到這樣的DB這exeuced(它仍然以最快的速度運行),並且仍然可以過濾它EF。

外連接總是與EF

Create View ViewMyShiningAss 
Begin 
/* select the outer join shit */ 
end 

更新EF模型屁股痛

using(var ctx = new MyModelEntities()) 
{ 
    var x = ctx.ViewMyShiningAss.ToList(); 
} 
+1

爲什麼這是一個答案 - 這聽起來像「我不知道如何做到這一點,所以我建議你做別的。」如果你不知道該怎麼做,不要回答這個問題。 – Hogan

+0

我與SQL查詢建議同意,我也同意,這應該是一個評論 – Tuco

+0

我很欣賞你的建議。謝謝。我嘗試了左連接並離開了外連接。它仍然是一樣的。我是否需要創建兩個查詢並在它們之間有一個聯合? – lama