2011-03-05 58 views
4

场景: 我有数据库表,存储另一个表的多对多关系的层次结构。一个项目可以有多个子项,也可以有多个父项。递归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<项目,项目>>其中关键是一个父项和组项目都是子项。
  • 理想情况下,我想要一个解决方案,实体提供者可以将其转换为T-SQL,但如果这不可行,那么我需要将往返次数减少到最少。
  • 我打算在叶节点上加入另一个表中存在的Sum值。

回答

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; 

对不起任何语法错误......

+0

谢谢你的发表!我以类似的方式实现了递归。 (+1)它适用于单元测试,但我仍然需要根据数据库进行测试。如果它运作良好,我会接受你的答案。 – 2011-03-07 02:10:25

0

好吧,如果层次结构是严格的2级可以随时工会他们,让LINQ理清SQL(它最终被行程单虽然它需要看到它有多快你的卷上运行数据):

var glist = from pc in hlist.AsEnumerable() 
      group pc.Child by pc.Parent into g 
      select new { Parent = g.Key, Children = g }; 

我以前AsEnumerable()这里我们到达LINQ SQ的能力:

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}>列表L提供商尝试将联盟分组。如果您尝试使用IQueryable,它会针对可资格的父母运行基本联盟,然后为每位父母进行往返(这是您想要避免的)。无论您是否使用常规的LINQ进行分组都取决于您,相同的数据量将不得不以任何方式通过管道。

编辑:或者,你可以建立一个视图链接到所有其子女的父视图,并使用该视图作为绑定项目的基础。从理论上讲,这应该允许你/ L2S在一次旅行中对它进行分组。

+0

我喜欢你的答案,但会有至少4个级别和层次结构将表驱动(用户配置的),所以有在运行时可以是任意数量的级别。出于这个原因,我会尝试使用递归,但是我担心往返会影响性能。我会稍后跟进。 – 2011-03-07 02:22:17

+0

你的等级有多大?如果你想减少往返旅行,我认为你应该考虑一下这个linq框。您可能想要探索的一些选项: 1.使用sql server层次结构支持并构建视图以生成结果,您将在一次调用中获取结果 2.如果层次结构表不是太大,只需加载整个结果在一勺,并建立一个层次结构分组客户端? – mmix 2011-03-07 10:42:59