I cannot figure out how to do a Linq.Dynamic
on an ObservableCollection
and sum some fields. 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;
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>
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. So hand coding the groups isn't an option. So while @Harald Coppoolse does work it requires that myClass.MyField to be hand coded.
So MyCollection
is a sequence of MyClass
objects, where every MyClass
object has at least two properties: MyField
and Total
.
You want the sum of all Total
values that have the same value for MyField
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; and one for the Y with a grand total of 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.
There is a lesser known GroupBy overload that will do this in one statement. 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.
Here is the new 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
;
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.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.