C# 操纵集合以生成压缩版本
我目前正被一个我似乎无法理解的小功能难倒 首先,我有一个C# 操纵集合以生成压缩版本,c#,c#-4.0,C#,C# 4.0,我目前正被一个我似乎无法理解的小功能难倒 首先,我有一个Stock类,如下所示: public class Stock { public int Id; public int LocationId; public int Quantity; } Stock日志从数据库返回,这些日志由另一项功能生成。日志表示为列表集合-但是我需要添加相同ID和LocationID组合的每个对象的数量属性,例如: 原始数据集: ID:1位置:1数量:20 ID:1位置:2数量:30 ID:
Stock
类,如下所示:
public class Stock
{
public int Id;
public int LocationId;
public int Quantity;
}
Stock
日志从数据库返回,这些日志由另一项功能生成。日志表示为列表
集合-但是我需要添加相同ID
和LocationID
组合的每个对象的数量
属性,例如:
原始数据集:
ID:1位置:1数量:20
ID:1位置:2数量:30
ID:1位置:1数量:30
ID:2位置:2数量:20
ID:1位置:2数量:30
ID:1位置:1数量:100
应返回:
压缩数据集:
ID:1位置:1数量:150
ID:1位置:2数量:60
ID:2位置:2数量:20
重申:数据集是从数据库动态返回的,不能保证会有每个ID
和LocationID
组合,我需要结果数据集在ID
和LocationID
的复合键上是唯一的
我不确定最有效的方法是什么,这阻碍了我的项目进展,任何建议或方法都将不胜感激。我认为这确实是一个知识差距,但我还没有找到任何适合我的要求(我想这是一个很奇怪的要求)
非常感谢,
Andy您可以使用
Enumerable.GroupBy
执行分组,并使用Enumerable.Aggregate
(在本例中,可以使用专门的Sum
)执行聚合
大致如下:
IEnumerable<Tuple<int, int, int>> result =
stocks.GroupBy(stock => new { id = stock.Id, locationId = stock.LocationId},
(key, s) => new { key.id, key.locationId, total = s.Sum(ss => ss.Quantity) });
foreach (var result in results)
{
Console.WriteLine(result.id);
Console.WriteLine(result.locationId);
Console.WriteLine(result.total);
}
IEnumerable结果=
GroupBy(stock=>new{id=stock.id,locationId=stock.locationId},
(key,s)=>new{key.id,key.locationId,total=s.Sum(ss=>ss.Quantity)});
foreach(结果中的var结果)
{
Console.WriteLine(result.id);
Console.WriteLine(result.locationId);
Console.WriteLine(result.total);
}
使用GroupBy
执行此操作:
var grouped = (from s in stocks
group s by new { s.Id, s.LocationId }
into grp
select new Stock()
{
Id = grp.Key.Id,
LocationId = grp.Key.LocationId,
Quantity = grp.Sum(x => x.Quantity)
}).ToList();
最好在数据库上执行此操作,但也可以使用GroupBy实现完全相同的效果:
public class Stock
{
public int Id;
public int LocationId;
public int Quantity;
}
static void Main(string[] args)
{
var list = new List<Stock>()
{
new Stock(){ Id = 1, LocationId = 1, Quantity = 20},
new Stock(){ Id = 1, LocationId = 2, Quantity = 30},
new Stock(){ Id = 1, LocationId = 1, Quantity = 30},
new Stock(){ Id = 2, LocationId = 2, Quantity = 20},
new Stock(){ Id = 1, LocationId = 2, Quantity = 30},
new Stock(){ Id = 1, LocationId = 1, Quantity = 100},
};
var grouped = list.GroupBy(c => new {Id = c.Id, LocationId = c.LocationId})
.Select(g => new
{
Id = g.Key.Id,
LocationId = g.Key.LocationId,
Quantity = g.Sum(a => a.Quantity)
});
foreach(var group in grouped.OrderBy(c => c.Id))
{
Console.WriteLine("Id:{0} - LocationId:{1} - Quantity:{2}", group.Id,
group.LocationId, group.Quantity);
}
}
公共类股票
{
公共int Id;
公共地址ID;
公共整数;
}
静态void Main(字符串[]参数)
{
var list=新列表()
{
new Stock(){Id=1,LocationId=1,Quantity=20},
新货(){Id=1,LocationId=2,Quantity=30},
new Stock(){Id=1,LocationId=1,Quantity=30},
新货(){Id=2,LocationId=2,Quantity=20},
新货(){Id=1,LocationId=2,Quantity=30},
new Stock(){Id=1,LocationId=1,Quantity=100},
};
var grouped=list.GroupBy(c=>new{Id=c.Id,LocationId=c.LocationId})
.选择(g=>new
{
Id=g.Key.Id,
LocationId=g.Key.LocationId,
数量=总数量(a=>a.数量)
});
foreach(grouped.OrderBy(c=>c.Id)中的var组)
{
WriteLine(“Id:{0}-LocationId:{1}-Quantity:{2}”,group.Id,
group.LocationId、group.Quantity);
}
}
我更喜欢使用类似以下内容的SQL查询:
select id, location, sum(quantity) quant from stocktable group by id, location
这有助于在数据库本身完成计算,从而在性能方面帮助您。由于DB服务器无论如何都会读取所有数据并将其提供给应用层,因此不会对性能造成任何损失,而且您可以从简单性方面获益 你没有在数据库中执行聚合有什么原因吗?我把它作为一个C#问题发布,并且有一些有用的C#答案帮助了我,我觉得有必要将其中一个标记为答案,但是我确实实现了你提出的建议,这是一个非常有用、简单的解决方案。非常感谢。谢谢你的回答,考虑到你提到在数据库中进行聚合(我最终还是这么做了),并且仍然给出了C#答案,这正是我想要的。非常感谢。