递归 Linq 分组
设想: 我有一个数据库表,它存储另一个表的多对多关系的层次结构。一项可以有多个子项,也可以有多个父项。
Items
------
ItemID (key)
Hierarchy
---------
MemberID (key)
ParentItemID (fk)
ChildItemID (fk)
示例层次结构:
Level1 Level2 Level3
X A A1
A2
B B1
X1
Y C
我想按层次结构中的每个父节点对所有子节点进行分组。
Parent Child
X A1
A2
B1
X1
A A1
A2
B B1
X1
Y C
- 请注意父列中没有叶节点,而子列仅包含叶节点。
- 理想情况下,我希望结果采用 IEnumerable<
IGrouping<
Item, Item>> 的形式,其中键是 Parent,组项都是 Children 。 - 理想情况下,我想要一个实体提供程序可以转换为 T-SQL 的解决方案,但如果不可能,那么我需要将往返次数保持在最低限度。
- 我打算对叶节点上连接的另一个表中存在的值求和。
Scenario:
I have database table that stores the hierarchy of another table's many-to-many relationship. An item can have multiple children and can also have more than one parent.
Items
------
ItemID (key)
Hierarchy
---------
MemberID (key)
ParentItemID (fk)
ChildItemID (fk)
Sample hierarchy:
Level1 Level2 Level3
X A A1
A2
B B1
X1
Y C
I would like to group all of the child nodes by each parent node in the hierarchy.
Parent Child
X A1
A2
B1
X1
A A1
A2
B B1
X1
Y C
- Notice how there are no leaf nodes in the Parent column, and how the Child column only contains leaf nodes.
- Ideally, I would like the results to be in the form of IEnumerable<
IGrouping<
Item, Item>> where the key is a Parent and the group items are all Children. - Ideally, I would like a solution that the entity provider can translate in to T-SQL, but if that is not possible then I need to keep round trips to a minimum.
- I intend to Sum values that exist in another table joined on the leaf nodes.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
既然您总是要返回表中的所有项目,为什么不直接创建一个递归方法来获取父级的所有子级,然后在内存中的项目上使用它:
那么:
对于任何语法错误,我们深表歉意。 。
Since you are always going to be returning ALL of the items in the table, why not just make a recursive method that gets all children for a parent and then use that on the in-memory Items:
then:
Sorry for any syntax errors...
好吧,如果层次结构严格为 2 级,您始终可以将它们合并并让 LINQ 整理 SQL(它最终会成为一次单程,但需要了解它在数据量上运行的速度):
这为您提供了一个扁平的
IEnumerable<{Item, Item}>
列表,因此如果您想对它们进行分组,您只需遵循:我在这里使用了
AsEnumerable()
因为我们达到了以下功能尝试对联合进行分组的 LINQ SQL 提供程序。如果您针对 IQueryable 尝试它,它将为符合条件的父母运行一个基本的 Union,然后为每个父母进行往返(这是您想要避免的)。是否可以使用常规 LINQ 进行分组取决于您,无论哪种方式,都必须通过管道传输相同量的数据。编辑:或者,您可以构建一个将父项链接到其所有子项的视图,并使用该视图作为绑定项目的基础。理论上,这应该允许您/L2S 通过一次旅行对其进行分组。
Well, if the hierarchy is strictly 2 levels you can always union them and let LINQ sort out the SQL (it ends up being a single trip though it needs to be seen how fast it will run on your volume of data):
This gives you an flat
IEnumerable<{Item, Item}>
list so if you want to group them you just follow on:I used
AsEnumerable()
here as we reached the capability of LINQ SQL provider with attempting to group a Union. If you try it against IQueryable it will run a basic Union for eligable parents then do a round-trip for every parent (which is what you want to avoid). Whether or not its ok for you to use regular LINQ for the grouping is up to you, same volume of data would have to come through the pipe either way.EDIT: Alternatively you could build a view linking parent to all its children and use that view as a basis for tying Items. In theory this should allow you/L2S to group over it with a single trip.