简体   繁体   English

Linq动态表达式Groupby和

[英]Linq Dynamic Expressions Groupby with sum

I cannot figure out how to do a Linq.Dynamic on an ObservableCollection and sum some fields. 我无法弄清楚如何在ObservableCollection上执行Linq.Dynamic并求和一些字段。 Basically I want to do this; 基本上我想这样做;

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)
     };

Figured it would be this in Linq.Dynamic; 在Linq.Dynamic中发现了这一点。

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

However this keeps give me errors. 但是,这总是给我错误。

FYI MyCollection is a ObservableCollection<MyClass> 仅供参考MyCollection是一个ObservableCollection<MyClass>

Edit: 编辑:

I am sorry did not make this very clear. 对不起,我没有说清楚。 The reason I need it to be Linq.Dynamic is that the actual MyClass has about 10 properties that user can pick to group the collection MyCollection in. To make matters worse is the user can select multiple grouping. 我需要使用Linq.Dynamic的原因是,实际的MyClass具有大约10个属性,用户可以选择将其MyCollection集合。更糟糕的是,用户可以选择多个分组。 So hand coding the groups isn't an option. 因此,手动编码组不是一种选择。 So while @Harald Coppoolse does work it requires that myClass.MyField to be hand coded. 因此,尽管@Harald Coppoolse可以正常工作,但需要对myClass.MyField进行手动编码。

So MyCollection is a sequence of MyClass objects, where every MyClass object has at least two properties: MyField and Total . 因此MyCollectionMyClass对象的序列,其中每个MyClass对象至少具有两个属性: MyFieldTotal

You want the sum of all Total values that have the same value for MyField 您希望MyField具有相同值的所有Total值之和

For example: 例如:

MyField  Total
   X       10
   Y        5
   X        7
   Y        3

You want a sequence with two elements: one for the X with a grand total of 10 + 7 = 17; 您需要一个包含两个元素的序列:一个用于X,总计10 + 7 = 17;另一个用于X。 and one for the Y with a grand total of 5 + 3 = 8 Y的一个,总计5 + 3 = 8

In method syntax: 在方法语法中:

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
    })

If your ObservableCollection is in fact an ObservableCollection<MyClass> than you won't need the Cast<MyClass> part. 如果您的ObservableCollection实际上是ObservableCollection<MyClass> ,则不需要Cast<MyClass>部分。

There is a lesser known GroupBy overload that will do this in one statement. 鲜为人知的GroupBy重载将在一个语句中完成。 I'm not sure if this one will improve readability: 我不确定这是否会提高可读性:

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
        });

So this might not be the best way, but it is the only I found. 因此,这可能不是最好的方法,但这是我发现的唯一方法。 FYI it more manual work than standard LINQ. 仅供参考,它比标准LINQ更为人工。

Here is the new Dynamic Linq; 这是新的Dynamic Linq;

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

The next problem is not only do you need to iterate through each MainID but you need to iterate through MyClass and sum for each MainID ; 下一个问题不仅是您需要遍历每个MainID而且还需要遍历MyClass和每个MainID

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

If someone can show me a better way to do this I will award the correct answer to that. 如果有人可以向我展示一种更好的方法,我将为此提供正确的答案。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM