在 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
我写了一个 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