C# 可观察集合的汇总总计<;MyType>;带着Linq表情

C# 可观察集合的汇总总计<;MyType>;带着Linq表情,c#,.net,linq,C#,.net,Linq,我有一个Silverlight委托,它在EventArgs结果中获得一个ObservableCollection。DTO myType包含Order、StartDate、Status、PlannedAmount、ActualAmount等字段。WCF服务端上的查询在每个订单上获得几行,仅根据PlannedAmount和ActualAmount变化 Order # | StartDate | PlannedAmount| ActualAmount | Order Comments .... Ord

我有一个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 ...
然后把它做成一个可观察的集合,和我以前做过的一样

我已经试过了,但是除了键和和和值之外,我似乎什么也得不到

    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查询类似。我相信我的思路是正确的,因为每个元素都有正确格式的数据。我仍然无法将结果设置为Silverlight网格的ItemsSource,在Linq出现所有混乱之前,我可以绑定它。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
    };

这不是一个可观察的集合,但事实证明,我根本不需要它。

我很确定

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

在我的编辑中添加了更多字段。这会改变它的工作方式吗?所有SelectMany表达式都会将字符串值转换为System.Collections.Generic.IEnumerable。这似乎不起作用,我仍然希望将结果转换为ObservableCollectionWith This line Location=g.First(wo=>wo.Location),我得到“无法将表达式类型‘string’转换为返回类型‘bool’。抱歉,在键入此答案时,我的大脑显然离开了一分钟。”。我已经纠正了。至少你有足够的头脑来理解这一点:)这比我的解决方案好。谢谢