我有两个列表:一个代表商店,另一个代表与这些商店关联的订单。这是一个简化版本 数据:
var stores = new[]
{
new { Code = 1, Name = "Store 1" },
new { Code = 2, Name = "Store 2" }
};
var orders = new[]
{
new { Code = 1, StoreCode = 1, TotalValue = 4.12 },
new { Code = 2, StoreCode = 1, TotalValue = 14.12 },
new { Code = 3, StoreCode = 1, TotalValue = 24.12 }
};
我正在尝试实现以下输出:
StoreName = Store 1 | TotalValue = 38.24
为了实现此目的,我使用 LINQ to Objects 中的组联接来聚合每个商店的订单。但是,我还需要根据应用于订单的条件来过滤结果。
这是我正在使用的查询:
var result = (from s in stores
join o in orders on s.Code equals o.StoreCode into grp
where grp.Any(o => o.TotalValue > 10)
select new
{
StoreName = s.Name,
TotalValue = grp.Sum(x => x.TotalValue)
}).ToList();
但是,我遇到了错误:当前上下文中不存在名称“o”。
这种场景下如何有效过滤orders表中的group join数据?
试试这个:
var result = (from s in stores
join o in orders.Where(x => x.TotalValue > 10) on s.Code equals o.StoreCode into grp
select new
{
StoreName = s.Name,
TotalValue = grp.Sum(x => x.TotalValue)
});
或者这个
var result = (from s in stores
join o in orders on s.Code equals o.StoreCode into grp
select new
{
StoreName = s.Name,
TotalValue = grp.Where(x => x.TotalValue > 10)
.Sum(x => x.TotalValue)
});
请注意,通常不需要调用
ToList
,因为这需要立即评估查询。大多数时候,将其保留为 IEnumerable<T>
就足够了。此外,这还将返回一行“Store 2”,带有 TotalValue = 0
。如果您也想省略这些行,您可以使用类似的内容。
var result = (from s in stores
join o in orders.Where(x => x.TotalValue > 10) on s.Code equals o.StoreCode into grp
let totalValue = grp.Sum(x => x.TotalValue)
where totalValue > 0
select new
{
StoreName = s.Name,
TotalValue = totalValue
});
或者这个
var result = (from s in stores
join o in orders on s.Code equals o.StoreCode into grp
let totalValue = grp.Where(x => x.TotalValue > 10)
.Sum(x => x.TotalValue)
where totalValue > 0
select new
{
StoreName = s.Name,
TotalValue = totalValue
});