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

如何使用LINQ按ComboUniqueId获取唯一ComboAmount并计算总和

问题分析与修复方案

先梳理下你代码里的几个核心问题,然后给你修正后的实现:

你当前代码的主要问题

  1. Distinct用法错误:Linq的Distinct默认是对比整个匿名对象的所有属性,没有直接接受“按指定字段去重”的重载。你需要用DistinctBy(.NET Core 3.0+、.NET 5及以上支持)或者GroupBy来实现按ComboUniqueId去重。
  2. 索引不匹配问题:循环里用this.OrderDetailArr[i]去取附加项是错误的——ListUnique是去重后的集合,它的索引和原数组完全没有对应关系,应该直接用去重后对象的ItemAddOnsArr。
  3. 套餐金额逻辑不符合预期:原代码里当ComboId != null时直接把FinalTotal赋值为ComboAmount,这会覆盖之前累加的所有总和,显然不是你想要的计算逻辑。

修正后的代码(推荐用DistinctBy,简洁高效)

decimal FinalTotal = 0;

// 按ComboUniqueId去重,拿到每个唯一套餐的相关数据
var uniqueCombos = this.OrderDetailArr
    .DistinctBy(x => x.ComboUniqueId)
    .Select(x => new {
        x.ComboAmount,
        x.ComboId,
        x.ItemAddOnsArr,
        x.TotalPrice
    });

foreach (var combo in uniqueCombos)
{
    // 先累加当前项的基础总价
    FinalTotal += combo.TotalPrice;

    // 如果是套餐,用套餐金额替换当前项的基础总价(如果是累加逻辑就改成+=)
    if (combo.ComboId != null)
    {
        FinalTotal -= combo.TotalPrice; // 先减去之前加的基础价
        FinalTotal += combo.ComboAmount; // 再加上套餐价
    }

    // 累加当前项的附加项总价
    if (combo.ItemAddOnsArr != null)
    {
        foreach (var addOn in combo.ItemAddOnsArr)
        {
            FinalTotal += addOn.AddOnTotalPrice;
        }
    }
}

如果你用的是旧版.NET(不支持DistinctBy),用GroupBy替代

decimal FinalTotal = 0;

// 按ComboUniqueId分组,取每组第一个元素作为唯一代表
var uniqueCombos = this.OrderDetailArr
    .GroupBy(x => x.ComboUniqueId)
    .Select(g => g.First())
    .Select(x => new {
        x.ComboAmount,
        x.ComboId,
        x.ItemAddOnsArr,
        x.TotalPrice
    });

// 后续循环逻辑和上面完全一致
foreach (var combo in uniqueCombos)
{
    FinalTotal += combo.TotalPrice;

    if (combo.ComboId != null)
    {
        FinalTotal -= combo.TotalPrice;
        FinalTotal += combo.ComboAmount;
    }

    if (combo.ItemAddOnsArr != null)
    {
        foreach (var addOn in combo.ItemAddOnsArr)
        {
            FinalTotal += addOn.AddOnTotalPrice;
        }
    }
}

关键改进点说明

  1. 正确实现按ComboUniqueId去重:用DistinctBy直接指定去重的键,或者GroupBy分组后取每组第一个元素,确保每个唯一的ComboUniqueId只保留一条数据。
  2. 避免索引混乱:用foreach遍历去重后的集合,直接操作当前套餐对象的属性,彻底解决原代码中索引不匹配的问题。
  3. 修正套餐金额计算逻辑:把“直接覆盖总和”改成“替换当前项的基础价为套餐价”,更符合常规的套餐计价逻辑(如果你的需求是累加套餐金额,直接把这两行改成FinalTotal += combo.ComboAmount即可)。
  4. 附加项匹配正确:直接遍历当前套餐的ItemAddOnsArr,确保附加项和对应的套餐一一对应。

内容的提问来源于stack exchange,提问作者Addi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 07:15:43