如何在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其他属性的处理逻辑 }) );
一些需要注意的细节
- INotifyPropertyChanged的正确性:因为我们创建了新的Repere和Operation实例,要确保这些新实例的INotifyPropertyChanged实现是完整的,否则UI绑定不会响应属性变化。
- 非QtyFinished属性的处理:如果Operation还有其他需要保留的属性,要根据业务规则确定取值方式(比如取第一个、最后一个,或者做其他处理)。
- 空值防护:如果
ListReperes或ListOperations可能为null,记得添加空值判断,避免出现NullReferenceException。
内容的提问来源于stack exchange,提问作者Siegfried.V
相关产品推荐
相关产品推荐

