[英]Roll up totals of an ObservableCollection<MyType> with a Linq expression
I have a Silverlight delegate which gets an ObservableCollection in the EventArgs Result. 我有一个Silverlight委托,该委托在EventArgs结果中获取一个ObservableCollection。 The DTO myType has fields Order, StartDate, Status, PlannedAmount, ActualAmount, and few others.
DTO myType具有字段Order,StartDate,Status,PlannedAmount,ActualAmount以及其他几个字段。 The query on the WCF service side gets several rows per Order, varying only by PlannedAmount and ActualAmount.
WCF服务端的查询为每个订单获取几行,仅因PlannedAmount和ActualAmount有所不同。
Order # | StartDate | PlannedAmount| ActualAmount | Order Comments ....
Order A | March 15 | 20.00 | 0.00 | Comment 1 ...
Order A | March 15 | 30.00 | 0.00 | Comment 1 ...
Order A | March 15 | 10.00 | 0.00 | Comment 1 ...
Order A | March 15 | 0.00 | 30.00 | Comment 1 ...
Order B | March 25 | 10.00 | 0 | Comment 2 ...
Order B | March 25 | 0.00 | 5.00 | Comment 2 ...
I would like to show only one row per Order and sum all the PlannedAmount and ActualAmount values. 我只想为每个订单显示一行,并对所有PlannedAmount和ActualAmount值求和。 I prefer to change this in the presentation layer as I don't know what other consumers of the WCF Operation require.
我更喜欢在表示层中更改此设置,因为我不知道WCF操作的其他使用者需要什么。 So I want to roll it up to...
所以我想将其汇总到...
Order # | StartDate | PlannedAmount| ActualAmount | Order Comments ....
Order A | March 15 | 60.00 | 30.00 | Comment 1 ...
Order B | March 25 | 10.00 | 5.00 | Comment 2 ...
And then make this an ObservableCollection of the same type that I had before. 然后将其设为与我以前相同类型的ObservableCollection。
I have tried this but I cannot seem to get anything but the Key and the Sum values. 我已经尝试过了,但是除了Key和Sum值之外,我似乎什么也没得到。
var Orders =
from wo in OrdersPerOperation
group wo by wo.OrderNo
into g
select new
{
OrderNo = g.Key,
Planned = g.Sum(wo => wo.Planned),
Actual = g.Sum(wo => wo.Actual),
OrderComments = g.Select(wo => wo.Equipment),
StartDate = g.Select(wo => wo.StartDate),
Status = g.Select(wo => wo.Status),
OrderType = g.Select(wo => wo.OrderType) //,...
};
Edit 编辑
Getting just the key and two sums is straight-forward: 仅获得密钥和两个和就很简单:
var Orders =
from wo in OrdersPerOperation
group wo by wo.OrderNo
into g
select new
{
OrderNo = g.Key,
Planned = g.Sum(wo => wo.Planned),
Actual = g.Sum(wo => wo.Actual)
}
The challenge is getting all of the other fields, which are repetitive to also show in the result. 挑战在于获取所有其他字段,这些字段必须重复显示在结果中。
EDIT 编辑
I made this guess that this might work like a self-referencing SQL query. 我猜想这可能像自引用SQL查询一样工作。 I believe I am on the right track with this, in that each element has data in the correct format.
我相信我在这方面是正确的,因为每个元素都具有正确格式的数据。 I still cannot set the results to the ItemsSource of the Silverlight grid, which I could bind, before all of this Linq confusion.
在所有这种Linq混乱之前,我仍然无法将结果设置为Silverlight网格的ItemsSource,可以绑定该项目。 The IDE warns me that FirstOrDefault is a possible NullReferenceException.
IDE警告我,FirstOrDefault是可能的NullReferenceException。
var workOrders = from wo in workOrdersPerOperation
group wo by wo.OrderNo
into g
select new
{
OrderNo = g.Key,
Planned = g.Sum(wo => wo.Planned),
Actual = g.Sum(wo => wo.Actual),
g.FirstOrDefault(wo => wo.OrderNo == g.Key).Location,
g.FirstOrDefault(wo => wo.OrderNo == g.Key).Equipment,
g.FirstOrDefault(wo => wo.OrderNo == g.Key).StartDate,
g.FirstOrDefault(wo => wo.OrderNo == g.Key).Status,
g.FirstOrDefault(wo => wo.OrderNo == g.Key).OrderType,
g.FirstOrDefault(wo => wo.OrderNo == g.Key).AccType,
g.FirstOrDefault(wo => wo.OrderNo == g.Key).WorkCenter,
g.FirstOrDefault(wo => wo.OrderNo == g.Key).Description,
g.FirstOrDefault(wo => wo.OrderNo == g.Key).Priority
};
Can anyone get me past this step? 有人可以让我越过这一步吗? I still need to bind it to the control.
我仍然需要将其绑定到控件。
您需要g.SelectMany(wo => wo.Equipment)
。
尝试:
OrderComments = g.Select(wo => wo.Equipment).ToList()
I found that I could select into a collection of new instances of MyClass with initializers. 我发现我可以选择带有初始化程序的MyClass新实例的集合。
var orders = from wo in ordersPerOperation
group wo by wo.OrderNo
into g
select new MyType()
{
OrderNo = g.Key,
Planned = g.Sum(wo => wo.Planned),
Actual = g.Sum(wo => wo.Actual),
Location = g.FirstOrDefault(wo => wo.OrderNo == g.Key).Location,
Equipment = g.FirstOrDefault(wo => wo.OrderNo == g.Key).Equipment,
StartDate = g.FirstOrDefault(wo => wo.OrderNo == g.Key).StartDate,
Status = g.FirstOrDefault(wo => wo.OrderNo == g.Key).Status,
OrderType = g.FirstOrDefault(wo => wo.OrderNo == g.Key).OrderType,
AccType = g.FirstOrDefault(wo => wo.OrderNo == g.Key).AccType,
WorkCenter = g.FirstOrDefault(wo => wo.OrderNo == g.Key).WorkCenter,
Description = g.FirstOrDefault(wo => wo.OrderNo == g.Key).Description,
Priority = g.FirstOrDefault(wo => wo.OrderNo == g.Key).Priority
};
This is not an ObservableCollection, but it turns out that I don't need it be after all. 这不是ObservableCollection,但事实证明我根本不需要它。
I'm pretty sure that this 我很确定
Location = g.FirstOrDefault(wo => wo.OrderNo == g.Key).Location,
Will produce the same result as this 将产生与此相同的结果
Location = g.FirstOrDefault().Location,
Additionally, you only need to use FirstOrDefault
if your collection might be empty. 此外,如果您的集合可能为空,则仅需要使用
FirstOrDefault
。 However, the group would not exist if there were no items in it. 但是,如果其中没有项目,则该组将不存在。 This allows you to simplify it down to this.
这使您可以简化它。
Location = g.First().Location,
You can make the final solution 您可以制定最终解决方案
var orders = from wo in ordersPerOperation
group wo by wo.OrderNo
into g
select new MyType
{
OrderNo = g.Key,
Planned = g.Sum(wo => wo.Planned),
Actual = g.Sum(wo => wo.Actual),
Location = g.First().Location,
Equipment = g.First().Equipment,
StartDate = g.First().StartDate,
Status = g.First().Status,
OrderType = g.First().OrderType,
AccType = g.First().AccType,
WorkCenter = g.First().WorkCenter,
Description = g.First().Description,
Priority = g.First().Priority
};
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.