繁体   English   中英

汇总一个ObservableCollection的总数 <MyType> 带有Linq表达式

[英]Roll up totals of an ObservableCollection<MyType> with a Linq expression

我有一个Silverlight委托,该委托在EventArgs结果中获取一个ObservableCollection。 DTO myType具有字段Order,StartDate,Status,PlannedAmount,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 ...

我只想为每个订单显示一行,并对所有PlannedAmount和ActualAmount值求和。 我更喜欢在表示层中更改此设置,因为我不知道WCF操作的其他使用者需要什么。 所以我想将其汇总到...

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 ...

然后将其设为与我以前相同类型的ObservableCollection。

我已经尝试过了,但是除了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) //,...
        };

编辑
仅获得密钥和两个和就很简单:

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

挑战在于获取所有其他字段,这些字段必须重复显示在结果中。

编辑
我猜想这可能像自引用SQL查询一样工作。 我相信我在这方面是正确的,因为每个元素都具有正确格式的数据。 在所有这种Linq混乱之前,我仍然无法将结果设置为Silverlight网格的ItemsSource,可以绑定该项目。 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
                };

有人可以让我越过这一步吗? 我仍然需要将其绑定到控件。

您需要g.SelectMany(wo => wo.Equipment)

尝试:

OrderComments = g.Select(wo => wo.Equipment).ToList()

我发现我可以选择带有初始化程序的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
    };

这不是ObservableCollection,但事实证明我根本不需要它。

我很确定

Location = g.FirstOrDefault(wo => wo.OrderNo == g.Key).Location,

将产生与此相同的结果

Location = g.FirstOrDefault().Location,

此外,如果您的集合可能为空,则仅需要使用FirstOrDefault 但是,如果其中没有项目,则该组将不存在。 这使您可以简化它。

Location = g.First().Location,

您可以制定最终解决方案

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.

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