最近在项目开发中由于种种原因,需要处理根据条件动态GroupBy。当然,我可以根据各种条件去构造一个方法返回dynamic,然后Group by。如下:
private static dynamic GroupBy(dynamic r)
{
int a = 1, b = 2;
if (a < b) return new { id = r.id};
else if (a == b) return new { name=rd.name };
else return new { a = r.a };
}
这样虽然能够解决问题,但是当GroupBy的维度较多时,比如6个维度,就会有C61 +C62+C63 +C64+C65+C66 = 6+15+20+15+6+1=63种可能。
这种严重影响了可读性,不能忍。于是得想个其他的办法。尝试用一个结构体来解决这个问题,在结构体里定义好所有的维度。例如:
struct groupby
{
public int id { get; set; }
public string name { get; set; }
public int a { get; set; }
public int b { get; set; }
public int c { get; set; }
public DateTime f { get; set; }
}
然后重写上面GroupBy方法:
private static groupby GroupBy(dynamic r)
{
groupby g = new groupby();
int a = 1, b = 2, c = 3, d = 4;
if (a < b) g.id = r.id;
if (b > c) g.name = r.name;
if (c < d) g.c = r.c;
return g;
}
然后动态查询:
List<People> list = new List<People>()
{
new People(){ a = 1, b =2 ,c =3, id = 4, name = "5"},
new People(){ a = 2, b =2 ,c =3, id = 4, name = "5"},
new People(){ a = 1, b =2 ,c =3, id = 4, name = "5"},
new People(){ a = 1, b =2 ,c =3, id = 4, name = "5"},
new People(){ a = 1, b =2 ,c =3, id = 4, name = "5"},
new People(){ a = 1, b =2 ,c =3, id = 4, name = "5"}
};
for (int i = 0; i < 2000000; i++)
{
list.Add(new People() { a = i, b = i, c = i, id = i, name = i.ToString() });
}
var q = list.GroupBy(i => GroupBy(i))
.Select(g => new { id = g.Key.id, name = g.Key.name, a = g.Sum(i => i.a), b = g.Sum(i => i.b), c = g.Sum(i => i.b) })
.ToList();
以上大功告成。