另类方式解决Linq to Object 动态Group By

最近在项目开发中由于种种原因,需要处理根据条件动态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();

 

以上大功告成。微笑

posted on 2014-03-21 13:05  Devin.Dong  阅读(818)  评论(1编辑  收藏  举报

导航