2014-09-26 44 views
0

假设我有一个DataTable,我想进行3级别分组(或将来甚至更多)。为了简化,我会要求2个级别。LINQ/Multiple GroupBy。哪一个是正确的,递归使用或链使用?

DataTable dt = getTable(); 

使用LINQ,我可以想到2种方法。首先,

var chainWay = dt.Rows.Cast<DataRow>().GroupBy(dr => new { A = dr["A"], B = dr["B"] }) 
             .GroupBy(g => new { g.Key.A }); 
foreach (var group in chainWay) 
{ 
    foreach (var group2 in group) 
    { 
     foreach (DataRow dr in group2) 
     { 

     } 
    } 
} 

;第二,

var recursiveWay = dt.Rows.Cast<DataRow>().GroupBy(dr => dr["A"]) 
          .Select(g => new { g.Key, G = g.GroupBy(dr => dr["B"]) }); 
foreach (var group in recursiveWay) 
{ 
    foreach (var group2 in group.G) 
    { 
     foreach (DataRow dr in group2) 
     { 

     } 
    } 
} 

哪条路是正确的吗?第一,第二还是其他?

会有任何性能差异吗?

请记住,我想对此进行推广(更多关卡)。

在此先感谢您的建议。

+1

我会选择第一个选项,因为它更具可读性,对于这个'会有什么性能差异吗?' - 进行基准测试并找出结果。 – DGibbs 2014-09-26 14:48:53

+2

这些甚至不会产生相同的结果,所以当他们实际上没有做同样的事情时,比较他们的表现是毫无意义的。 – Servy 2014-09-26 14:53:13

+0

@Servy你是对的。它们不是相同的类型,但非常相似。有了非常小的差异,我可以迭代并执行相同的操作(只是编辑了问题)。如果我能决定选择哪一个,那么很容易调整这些循环。 – serdar 2014-09-26 15:08:00

回答

0

这似乎接近“主要基于意见”。这是我多次使用的第三个选项。它更冗长,但我认为它使结构更清晰。它也很容易看到嵌套的重复性,因此很容易推广到更多的分组。

var query = source.GroupBy(
    x => x.A, 
    (a, aGroup) => new 
    { 
     A = a, 
     Items = aGroup.GroupBy(
      x => x.B, 
      (b, bGroup) => new 
      { 
       B = b, 
       Items = bGroup 
      }) 
    }); 

被实例化的匿名对象当然可以用你的适当的类来替换。

+0

递归的一种方法。感谢提醒我,GroupBy有其他重载。 – serdar 2014-09-29 08:23:47