在 LINQ 表达式中查找条目的总和

Finding Aggregate Sum of entries in a LINQ expression

我写了一个 LINQ 查询,return是一组基于 JOIN 条件的对象(匿名类型)

var customerOrderResponse = tableOne.Join(
                    tableTwo,
                    firstData => firstData.BookingId,
                    secData => secData.OrderBookingId,
                    (firstData, secData) => new 
                    {
                        OrderNumber = firstData.Name,
                        Weight = firstData.Weight,
                        WeightUnit = firstData.WeightUnit,  //string = KG
                        Volume = firstData.Volume, 
                        VolumeUnit = firstData.VolumeUnit,   ////string = CUBIC-MTR
                        PackageQuantity = firstData.PackageQuantity,
                        PackageQuantityUnit = firstData.PackageQuantityUnit, // 
                        CustomerProductQuantity = firstData.CustomerProductQuantity,
                        CustomerProductQuantityUnit = firstData.CustomerProductQuantityUnit,
                        
                    }).GroupBy(co => co.CustomerOrderNumber).Select(s => s.First());

LINQ查询returns 0,1 or many entries of Anonymous type based on the join condition in the database. 我的问题是需要在查询中修改什么以获得某些列的总和

例如:

体重=firstData.Weight, 体积 = firstData.Volume, 包裹数量 = firstData.PackageQuantity,

如何将上述查询修改为 return 预期的方式

如果您想要单个客户订单中所有商品的总重量和体积,您可以这样做:

var customerOrderResponse = tableOne.Join(
        tableTwo,
        firstData => firstData.BookingId,
        secData => secData.OrderBookingId,
        (firstData, secData) => new
        {
            OrderNumber = firstData.Name,
            Weight = firstData.Weight,
            WeightUnit = firstData.WeightUnit,  //string = KG
            Volume = firstData.Volume,
            VolumeUnit = firstData.VolumeUnit,   ////string = CUBIC-MTR
            PackageQuantity = firstData.PackageQuantity,
            PackageQuantityUnit = firstData.PackageQuantityUnit, // 
            CustomerProductQuantity = firstData.CustomerProductQuantity,
            CustomerProductQuantityUnit = firstData.CustomerProductQuantityUnit,

        }).GroupBy(co => co.OrderNumber)
        .Select(items => new
        {
            Items = items,
            TotalVolume = items.Sum(x => x.Volume), // beware of unit.
            TotalWeight = items.Sum(x => x.Weight), // beware of unit.
        })         
        .Select(s => s.First());

但要确保在同一单元中添加卷,然后还要跟踪该单元。质量等也是如此...

要转换为通用单位,首先选择一个通用单位并对转换后的值求和:

.Select((items) =>
{
    string commonVolumeUnit = items.FirstOrDefault()?.VolumeUnit;
    string commonWeightUnit = items.FirstOrDefault()?.WeightUnit;

    return new
    {
        Items = items,
        VolumeUnit = items.FirstOrDefault()?.VolumeUnit,
        WeightUnit = items.FirstOrDefault()?.WeightUnit,
        TotalVolume = items.Sum(x => ConvertVolume(x.Volume, x.VolumeUnit, commonVolumeUnit)),
        TotalWeight = items.Sum(x => ConvertWeight(x.Weight, x.WeightUnit, commonWeightUnit)),
    };
})

然后您可以通过新匿名类型的项目 属性 访问每个单独的项目。

当项目源是可枚举的(不是列表,也不是数组等)时,最好'buffer'将项目作为列表:

.Select((items) =>
{
    var itemsList = items.ToList();

    string commonVolumeUnit = itemsList.FirstOrDefault()?.VolumeUnit;
    string commonWeightUnit = itemsList.FirstOrDefault()?.WeightUnit;

    return new
    {
        Items = itemsList,
        VolumeUnit = commonVolumeUnit ,
        WeightUnit = commonWeightUnit ,
        TotalVolume = itemsList.Sum(x => ConvertVolume(x.Volume, x.VolumeUnit, commonVolumeUnit)),
        TotalWeight = itemsList.Sum(x => ConvertWeight(x.Weight, x.WeightUnit, commonWeightUnit)),
    };
})



为了完整起见:这是我对上述内容的完整测试代码:(在 fiddle 上,因此您可以测试:https://dotnetfiddle.net/gYOzrg


编辑:因为您想要一个对象中的所有属性;你可以这样做:(也在 fiddle 上:https://dotnetfiddle.net/DWORbJ

var customerOrderResponse =
    tableOne.Join(
        tableTwo,
        firstData => firstData.BookingId,
        secData => secData.OrderBookingId,
        (firstData, secData) => new
        {
            FirstData = firstData,
            SecondData = secData,
            OrderNumber = firstData.Name,
            Weight = firstData.Weight,
            WeightUnit = firstData.WeightUnit,  //string = KG
            Volume = firstData.Volume,
            VolumeUnit = firstData.VolumeUnit,   ////string = CUBIC-MTR
            PackageQuantity = firstData.PackageQuantity,
            PackageQuantityUnit = firstData.PackageQuantityUnit, // 
            CustomerProductQuantity = firstData.CustomerProductQuantity,
            CustomerProductQuantityUnit = firstData.CustomerProductQuantityUnit,

        }).GroupBy(co => co.OrderNumber)

        .Select((items) =>
        {
            var itemsList = items.ToList();

            string commonVolumeUnit = itemsList[0].VolumeUnit;
            string commonWeightUnit = itemsList[0].WeightUnit;

            return new
            {
                Items = itemsList,
                TotalVolume = itemsList.Sum(x => ConvertVolume(x.Volume, x.VolumeUnit, commonVolumeUnit)),
                TotalWeight = itemsList.Sum(x => ConvertWeight(x.Weight, x.WeightUnit, commonWeightUnit)),
                TotalVolumeUnit = commonVolumeUnit,
                TotalWeightUnit = commonWeightUnit,
            };
        })
        .SelectMany((fullOrderData) =>
        {
            return fullOrderData.Items.Select(x =>
            {
                return new
                {
                    TotalVolume = fullOrderData.TotalVolume,
                    TotalWeight = fullOrderData.TotalWeight,
                    TotalVolumeUnit = fullOrderData.TotalVolumeUnit,
                    TotalWeightUnit = fullOrderData.TotalWeightUnit,
                    OrderNumber = x.OrderNumber,
                    Weight = x.Weight,
                    WeightUnit = x.WeightUnit,  //string = KG
                    Volume = x.Volume,
                    VolumeUnit = x.VolumeUnit,   ////string = CUBIC-MTR
                    PackageQuantity = x.PackageQuantity,
                    PackageQuantityUnit = x.PackageQuantityUnit, // 
                    CustomerProductQuantity = x.CustomerProductQuantity,
                    CustomerProductQuantityUnit = x.CustomerProductQuantityUnit,

                };
            });
        })
        .GroupBy(co => co.OrderNumber)
        .Select(x => x.First());


double totalWeight = customerOrderResponse.First().TotalWeight; // reads 47
double totalVolume= customerOrderResponse.First().TotalVolume; // reads 31