Linq SelectMany 包含父级。

12

我有以下三个Linq To Sql实体:Location、Institution和Building。

Location表只包括LocationId和LocationTypeId两列。

Institution和Building都通过一对一的关系从Location表中获取它们的Ids,并且Institution表与Building表之间有一对多的关系。

我想返回一个机构及其所有子级的所有位置记录。以下查询返回我需要的内容,但是缺少父机构位置记录。

var query = dc.Locations.SelectMany(l => l.Institutions, (loc, inst) => new { loc, inst })
                        .SelectMany(i => i.inst.Buildings, (locInst, bld) => bld.Location );
我该如何将父项与其子项一起包含?

具有相关列的ERD

更新:

如果在原始位置查询上使用联合,我可以获取想要的记录,但我仍然想知道这是否是最佳解决方案。 这是使用Union的代码。

IQueryable<Location> locations = dc.Locations;

locations.SelectMany(l => l.Institutions, (loc, inst) => new { loc, inst })
         .SelectMany(i => i.inst.Buildings, (locInst, bld) => bld.Location)
         .Union(locations);

你能发布实体类吗?至少足够展示它们之间的关系吗? - Dan Nixon
@DanNixon 我已经添加了实体类的图像,其中包含相关列。 - user2023116
除非您确实需要不同的值而不仅仅是连接,否则最好使用Concat而不是Union。虽然我不能确定,但我相信Concat将映射到SQL中的Union All,这将更具性能。 - erdomke
@erdomke 您是正确的,Concat确实在SQL中映射到Union All,但是,在我的情况下,我确实希望得到不同的值。 - user2023116
2个回答

6

这是一个棘手的问题,我认为很难再有更好的解决方法了。但如果你想按照某种顺序排序,比如首先按机构位置排序,然后按机构建筑物位置排序,你可以这样做:

locations.SelectMany(l => l.Institutions, (loc, inst) => new { loc, inst })
         .SelectMany(i => i.inst.Buildings.Union(new List<Building> { new Building { Location = i.loc } }), (locInst, bld) => bld.Location);

但是从这里开始,代码并没有变得更加简洁,你的解决方案十分直观且能完成任务。

这将会影响性能并且会消耗更多内存(如果这很重要),但是如果这正是你想要的,我希望它有所帮助。(因为位置储存的顺序不同)


0

这样怎么样:

        var t = from p in allParents
                from c in p.Children
                select new { Parent = p, Child = c };

请添加更多细节以扩展您的答案,例如工作代码或文档引用。 - Community

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接