我正在使用GroupBy创建一组用于多个子网格的分层组。
假设我的查询包含6列,a,b,c,d,e,f。
现在,我需要按a分组,然后按b分组,然后按c分组。并返回c组中的整行。
var q = rows.GroupBy(x => x.a)
好的,那太好了。那给了我我的小组。接下来,我们希望用a和b对它们进行分组。
var q1 = q.Select(g =>new {
Key = g.Key,
SubGroup = g.GroupBy(x => x.b)
}
好的,这也很好用。我得到了一组带有b的子组的。
现在我被困在第三级了。我尝试了各种语法,但大多数都不会编译。那些没有给出正确结果的那些。
var q2 = q1.Select(g1 => new {
Key = g1.Key,
SubGroup = g1.GroupBy(x => x.c)
}
这不编译。告诉我g1上没有GroupBy。
var q2 = q.Select(g1 => new {
Key = g1.Key,
SubGroup = g1.GroupBy(x => x.c)
}
这不会给我b子组,只给出a和c。
知道我在这里做错了什么?
编辑:
以下也不起作用,说没有g1.Key的定义
var q2 = q.Select(g => new {
Key = g.Key,
SubGroup = g.Select(g1 => new {
Key = g1.Key
SubGroup = g1.GroupBy(a => a.c)
})
我对内部的工作缺乏把握。
答案 0 :(得分:5)
现在,我不是说这实际上是一种好方法;它可能会很慢,如果性能很重要,正确的方法可能是按照这些不同的标准对整个集合进行排序,然后查看已排序集合的不同部分。
但是,如果您想使用GroupBy
和IGroupings
来管理它,那么您正在从错误的一端开始工作。你想先从最深层开始,然后再开始工作。
var groups = rows
.GroupBy(x => new { x.A, x.B, x.C, x.D, x.E, x.F })
.GroupBy(x => new { x.Key.A, x.Key.B, x.Key.C, x.Key.D, x.Key.E })
.GroupBy(x => new { x.Key.A, x.Key.B, x.Key.C, x.Key.D, })
.GroupBy(x => new { x.Key.A, x.Key.B, x.Key.C })
.GroupBy(x => new { x.Key.A, x.Key.B })
.GroupBy(x => x.Key.A);
groups.First().Key; // will be an A value
groups.First().First().First(); // will be an A, B, C group
答案 1 :(得分:2)
GroupBy实际上支持提供要分组的元素列表。每组将包含相同的前3项(A,B和C)。您可以使用.Key方法获取密钥,并使用foreach来处理不同的行。参见示例:
var groups = Elements.GroupBy(x => new {x.A, x.B, x.C});
foreach (var group in groups)
{
Trace.WriteLine(group.Key + ": " + group.Count());
foreach (var row in group)
{
Trace.WriteLine(row.D);
}
}
编辑:啊,好的 - 你需要的是这个:
var groups = Elements
.GroupBy(a => new {a.A})
.Select(g1 => new {
A = g1.Key,
Groups = g1
.GroupBy(b=> new {b.B})
.Select(g2 => new {
B = g2.Key,
Groups = g2
.GroupBy(c => new {c.C})
.Select(g3 => new {
C = g3.Key,
Rows = g3
})
})
});
foreach (var groupA in groups)
{
Trace.WriteLine(groupA.A);
foreach (var groupB in groupA.Groups)
{
Trace.WriteLine("\t" + groupB.B);
foreach (var groupC in groupB.Groups)
{
Trace.WriteLine("\t\t" + groupC.C);
foreach (var row in groupC.Rows)
{
Trace.WriteLine("Row: " + row.ToString());
}
}
}
}