You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在C#中按Repere名称分组并合并汇总Operation集合?

看起来你已经找对了方向,针对你这个层级数据的汇总需求,我整理了两种更优雅的实现方式,既满足ObservableCollection的要求,又能让代码更整洁易维护:

方案一:用Linq一步完成Repere分组+Operation汇总

你可以把Repere分组和Operation汇总的逻辑整合到一段Linq查询里,代码紧凑且可读性强。这里我稍微优化了你提到的代码,用分组键go.Key代替go.First().ID,更直接高效:

// 假设你有Contract的实例contract
var groupedAndSummarizedReperes = new ObservableCollection<Repere>(
    contract.ListReperes
        .GroupBy(repere => repere.Name)
        .Select(group => new Repere
        {
            Name = group.Key,
            // 合并当前分组下所有Repere的Operation并汇总
            ListOperations = new ObservableCollection<Operation>(
                group.SelectMany(repere => repere.ListOperations)
                    .GroupBy(op => op.ID)
                    .Select(opGroup => new Operation
                    {
                        ID = opGroup.Key,
                        QtyFinished = opGroup.Sum(op => op.QtyFinished),
                        Color = opGroup.First().Color,
                        // 这里按需添加Operation的其他属性,比如取分组中第一个实例的值
                    })
            ),
            // 如果Repere还有其他属性,根据需求处理,比如取分组中第一个Repere的对应值
            // ExampleProperty = group.First().ExampleProperty
        })
);

方案二:在Operation类中封装汇总逻辑

如果这个汇总逻辑需要在多处复用,或者想让代码职责更清晰,最好把Operation的汇总逻辑封装成静态方法放到Operation类里:

public class Operation : INotifyPropertyChanged
{
    // 你的现有属性及INotifyPropertyChanged实现
    public int ID { get; set; }
    public int QtyFinished { get; set; }
    public string Color { get; set; }

    // ... 这里省略INotifyPropertyChanged的接口实现代码

    // 静态方法:传入Operation集合,返回汇总后的ObservableCollection
    public static ObservableCollection<Operation> Summarize(IEnumerable<Operation> operations)
    {
        if (operations == null)
            throw new ArgumentNullException(nameof(operations));

        var summarizedOps = operations
            .GroupBy(op => op.ID)
            .Select(opGroup => new Operation
            {
                ID = opGroup.Key,
                QtyFinished = opGroup.Sum(op => op.QtyFinished),
                Color = opGroup.First().Color,
                // 其他属性按业务需求取值
            });

        return new ObservableCollection<Operation>(summarizedOps);
    }
}

使用的时候就非常简洁了:

var groupedReperes = new ObservableCollection<Repere>(
    contract.ListReperes
        .GroupBy(r => r.Name)
        .Select(group => new Repere
        {
            Name = group.Key,
            ListOperations = Operation.Summarize(group.SelectMany(r => r.ListOperations))
            // Repere其他属性的处理逻辑
        })
);

一些需要注意的细节

  1. INotifyPropertyChanged的正确性:因为我们创建了新的Repere和Operation实例,要确保这些新实例的INotifyPropertyChanged实现是完整的,否则UI绑定不会响应属性变化。
  2. 非QtyFinished属性的处理:如果Operation还有其他需要保留的属性,要根据业务规则确定取值方式(比如取第一个、最后一个,或者做其他处理)。
  3. 空值防护:如果ListReperes或ListOperations可能为null,记得添加空值判断,避免出现NullReferenceException。

内容的提问来源于stack exchange,提问作者Siegfried.V

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 09:12:54