LINQ查询外连接父和子(嵌套)表

时间:2016-02-05 14:02:17

标签: c# linq

我有三个级别的表和#34;董事","经理"和#34;领导者"他们之间有一对多的关系。

我想将董事,经理和领导的所有行与他们的子女关系分开。(也许是LeftOuterJoin)

例如,Directors表有

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导演1 1导演1 1经理1 1导演1 1经理1 1领导1 1导演1 1经理1 2领导1 1 Director1 2 Manager2

我的linq查询仅产生3行

DirID DirectorName MgrID ManagerName LdrID LeaderName

1 Director1 1 Manager1 1 Leader1
1导演1 1经理1 2领导1 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()

感觉就像一个小小的调整。只是不能做对。谁能帮帮我吗?谢谢。

2 个答案:

答案 0 :(得分: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
        }))
    ))
);

答案 1 :(得分:0)

我建议您编写一个SQL查询,将其放入sql View并将其映射为EF实体。这样你就可以在数据库中执行此操作(它仍然是最快的运行),并且仍然可以在EF中过滤它。

外部联接总是一个痛苦的EF

{
   "EntityA" : {
    "Id" : "317238621736"}
}

更新EF模型

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