Linq动态表达式Groupby和

时间:2018-09-21 19:54:33

标签: c# linq

我无法弄清楚如何对Linq.Dynamic进行ObservableCollection并求和一些字段。基本上我想这样做;

var group
     from x in MyCollection
     group x by x.MyField into g
     select new MyClass
     {
         MyField = g.Key,
         Total = g.Sum(y => y.Total)
     };

在Linq.Dynamic中发现了这一点;

var dGroup = MyCollection
             .GroupBy("MyField ", "it")
             .Select("new (it.Key as MyField , it as new MyClass { Total  = sum(it.Total ) })");

但这总是给我带来错误。

FYI MyCollectionObservableCollection<MyClass>

编辑:

对不起,我对此没有说清楚。我之所以需要使用Linq.Dynamic是因为实际的MyClass具有大约10个属性,用户可以选择将其归入集合MyCollection。更糟糕的是,用户可以选择多个分组。因此,手动编码组不是一种选择。因此,尽管@Harald Coppoolse可以正常工作,但需要对myClass.MyField进行手动编码。

2 个答案:

答案 0 :(得分:1)

因此MyCollectionMyClass对象的序列,其中每个MyClass对象至少具有两个属性:MyFieldTotal

您希望所有Total的值都相同的MyField的总和

例如:

MyField  Total
   X       10
   Y        5
   X        7
   Y        3

您想要一个包含两个元素的序列:一个用于X,总计10 + 7 = 17;另一个用于X。 Y的一个,总计5 + 3 = 8

使用方法语法:

var result = MyCollection.Cast<MyClass>()      // take all elements of MyCollection
    .GroupBy(myClass => myClass.MyField)       // Group into groups with same MyField
    .Select(group => new MyClass()             // for every group make one new MyClass object
    {
        MyField = group.Key,
        Total = group                          // to calculate the Total:
            .Select(groupElement => groupElement.Total) // get Total for all elements in the group
            .Sum(),                                     // and sum it
    })

如果您的ObservableCollection实际上是ObservableCollection<MyClass>,则不需要Cast<MyClass>部分。

有一个鲜为人知的GroupBy overload可以在一个语句中执行此操作。我不确定这是否会提高可读性:

var result = MyCollection.Cast<MyClass>()   // take all elements of MyCollection
    .GroupBy(myClass => myClass.MyField,    // group into groups with same MyField
        myClass => myClass.Total,           // for every element in the group take the Total
        (myField, totals) => new MyClass()  // from the common myField and all totals in the group
        {                                   // make one new MyClass object
            MyField = myField,              // the common myField of all elements in the group
            Total = totals.Sum(),           // sum all found totals in the group
        });

答案 1 :(得分:0)

所以这可能不是最好的方法,但这是我发现的唯一方法。仅供参考,它比标准的LINQ更为人工。

这是新的Dynamic Linq;

var dGroup = MyCollection
         .GroupBy("MyField ", "it")
         .Select("new (it.Key as MainID, it as MyClass)");

下一个问题不仅是您需要遍历每个MainID,而且还需要遍历MyClass并对每个MainID求和;

foreach (dynamic r in dGroup)
{
        foreach (dynamic g in r.MyClass)
        {
               gTotal = gTotal + g.Total;
        }
 }

如果有人可以向我展示一种更好的方法,我将为此提供正确的答案。