方案: 我有数据库表,存储另一个表的多对多关系的层次结构。一个项目可以有多个子项,也可以有多个父项。
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
IGrouping<
项目,项目&gt;&gt; 的形式,其中密钥是父级,组项目都是子级。 答案 0 :(得分:1)
由于您总是要返回表中的所有项,为什么不只是创建一个递归方法来获取父项的所有子项,然后在内存项上使用它:
partial class Items
{
public IEnumerable<Item> GetAllChildren()
{
//recursively or otherwise get all the children (using the Hierarchy navigation property?)
}
}
然后:
var items =
from item in Items.ToList()
group new
{
item.itemID,
item.GetAllChildren()
} by item.itemID;
对于任何语法错误抱歉...
答案 1 :(得分:0)
好吧,如果层次结构严格为2级,你可以随时将它们联合起来,让LINQ整理出SQL(虽然需要看看它在你的数据量上运行的速度有多快,但它最终只是一次旅行):
var hlist = from h in Hierarchies
select new {h.Parent, h.Child};
var slist = from h in Hierarchies
join h2 in hlist on h.Parent equals h2.Child
select new {h2.Parent, h.Child};
hlist = hlist.Union(slist);
这会为您提供一个单独的IEnumerable<{Item, Item}>
列表,因此如果您想对它们进行分组,请按照以下步骤操作:
var glist = from pc in hlist.AsEnumerable()
group pc.Child by pc.Parent into g
select new { Parent = g.Key, Children = g };
我在这里使用了AsEnumerable()
,因为我们在尝试对Union进行分组时达到了LINQ SQL提供程序的功能。如果您针对IQueryable进行尝试,它将为可资格父母运行一个基本联盟,然后为每个父母进行往返(这是您想要避免的)。无论您是否可以使用常规LINQ进行分组,都可以通过管道获得相同数量的数据。
编辑:或者,您可以构建一个将父级链接到其所有子级的视图,并将该视图用作绑定项目的基础。从理论上讲,这应该允许你/ L2S通过一次旅行对其进行分组。