简体   繁体   English

LINQ查询外部联接的父级和子级(嵌套)表

[英]LINQ Query for outerjoining Parent and child (nested) tables

I have three levels of tables "Directors", "Managers" and "Leaders" with one to many relationship between them. 我有三个级别的表“ Director”,“ Managers”和“ Leaders”,它们之间具有一对多的关系。

I would like to bring All the rows from Directors, Managers and Leaders separately along with their children relationship.(maybe LeftOuterJoin) 我想将来自董事,经理和领导者的所有信息以及他们的子女关系分开。(也许是LeftOuterJoin)

For example Directors table have 例如Directors表有

DirectorID DirectorName DirectorID DirectorName

     1            Director1 

Managers 经理

Manager ID Director ID Manager Name 经理ID董事ID经理姓名

  1              1                 Manager 1
  2              1                 Manager 2

Leaders 领导者

Leader ID Manager ID Leader Name 主管ID主管ID主管名称

  1                 1              Leader 1  
  2                 1              Leader 2

I want the query to return 我希望查询返回

DirID DirectorName MgrID ManagerName LdrID LeaderName DirID DirectorName MgrID ManagerName LdrID LeaderName

1 Director1 1名导演1
1 Director1 1 Manager1 1总监1 1经理1
1 Director1 1 Manager1 1 Leader1 1总监1 1经理1 1领导1
1 Director1 1 Manager1 2 Leader1 1总监1 1经理1 2领导1
1 Director1 2 Manager2 1总监1 2经理2

My linq query only results 3 rows 我的linq查询仅结果3行

DirID DirectorName MgrID ManagerName LdrID LeaderName DirID DirectorName MgrID ManagerName LdrID LeaderName

1 Director1 1 Manager1 1 Leader1 1总监1 1经理1 1领导1
1 Director1 1 Manager1 2 Leader1 1总监1 1经理1 2领导1
1 Director1 2 Manager2 1总监1 2经理2

             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()

It feels like a small tweak. 感觉就像一个小的调整。 just can't get it right. 就是做对了。 can anyone please help me? 谁能帮帮我吗? Thank you. 谢谢。

It feels like a small tweak 感觉就像一个小调整

Well, not exactly. 好吧,不完全是。 The result format in SQL is produced by so called ROLLUP query which is not supported natively by LINQ. SQL中的结果格式由所谓的ROLLUP查询产生,LINQ本身不支持该查询格式。 GroupJoin will gather the information needed, but flattening it the way you want is quite hard as you may see below (combinations of singe item array concatenating the group join groups). GroupJoin将收集所需的信息,但是要按所需的方式对其进行拼合非常困难,如下所示(将单项数组组合成组并加入组)。 Check it out: 看看这个:

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
        }))
    ))
);

I would suggest you to write a SQL query, put it into a sql View and map it as an EF entity. 我建议您编写一个SQL查询,将其放入sql View并将其映射为EF实体。 This way you get this exeuced in the DB (it's still the fastest to run) and can still filter it in EF. 这样,您就可以在数据库中执行此操作(它仍然是运行速度最快的),并且仍然可以在EF中对其进行过滤。

outer joins are always a pain in the ass with EF 外联始终是EF痛苦中的难题

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

Update the EF model 更新EF模型

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM