选择多个字段group by和sum
我想用linq(对象列表)进行查询,我真的不知道怎么做,我可以做组和总和但不能选择其余的字段。 例:
ID Value Name Category 1 5 Name1 Category1 1 7 Name1 Category1 2 1 Name2 Category2 3 6 Name3 Category3 3 2 Name3 Category3
我希望按ID分组,按值按SUM分组并返回所有这样的字段。
ID Value Name Category 1 12 Name1 Category1 2 1 Name2 Category2 3 8 Name3 Category3
更新:如果您尝试避免对所有字段进行分组,则可以按Id
进行分组:
data.GroupBy(d => d.Id) .Select( g => new { Key = g.Key, Value = g.Sum(s => s.Value), Name = g.First().Name, Category = g.First().Category });
但是此代码假定对于每个Id
,应用相同的Name
和Category
。 如果是这样,你应该考虑正常化,因为@Aron建议。 这意味着将Id
和Value
保留在一个类中,并将Name
, Category
(以及相同Id
任何其他字段将相同)移动到另一个类,同时还具有Id
作为参考。 规范化过程减少了数据冗余和依赖性。
void Main() { //Me being lazy in init var foos = new [] { new Foo { Id = 1, Value = 5}, new Foo { Id = 1, Value = 7}, new Foo { Id = 2, Value = 1}, new Foo { Id = 3, Value = 6}, new Foo { Id = 3, Value = 2}, }; foreach(var x in foos) { x.Name = "Name" + x.Id; x.Category = "Category" + x.Id; } //end init. var result = from x in foos group x.Value by new { x.Id, x.Name, x.Category} into g select new { g.Key.Id, g.Key.Name, g.Key.Category, Value = g.Sum()}; Console.WriteLine(result); } // Define other methods and classes here public class Foo { public int Id {get;set;} public int Value {get;set;} public string Name {get;set;} public string Category {get;set;} }
试试这个:
var objList = new List(); objList.Add(new SampleObject() { ID = 1, Value = 5, Name = "Name1", Category = "Catergory1"}); objList.Add(new SampleObject() { ID = 1, Value = 7, Name = "Name1", Category = "Catergory1"}); objList.Add(new SampleObject() { ID = 2, Value = 1, Name = "Name2", Category = "Catergory2"}); objList.Add(new SampleObject() { ID = 3, Value = 6, Name = "Name3", Category = "Catergory3"}); objList.Add(new SampleObject() { ID = 3, Value = 2, Name = "Name3", Category = "Catergory3"}); var newList = from val in objList group val by new { val.ID, val.Name, val.Category } into grouped select new SampleObject() { ID = grouped.ID, Value = grouped.Sum(), Name = grouped.Name, Category = grouped.Category };
检查LINQPad:
newList.Dump();
如果你的课程很长并且你不想复制所有的东西,你可以尝试这样的事情:
l.GroupBy(x => x.id). Select(x => { var ret = x.First(); ret.value = x.Sum(xt => xt.value); return ret; }).ToList();
有了巨大的力量,责任就来了。 你需要小心。 行ret.value = x.Sum(xt => xt.value)
将更改原始集合,因为您正在传递引用,而不是新对象。 如果你想避免它,你需要在你的类中添加一些Clone
方法,如MemberwiseClone
(但同样,这将创建浅拷贝,所以要小心)。 只需用以下代码替换行: var ret = x.First().Clone();
- ConnectionString中未指定OLE DB提供程序。 “提供商= SQLOLEDB;
- 我可以使用reflection来查找ASP.NET中的bin / 文件夹而不是asp临时文件夹
- 带有entity framework的强类型ASP.NET MVC
- ObjectContext.ExecuteStoreCommand,如何在调用之间清除参数?
- 设置STS但在webapp中保留formsauthentication
- 如何从子页面控制asp.net母版页上的元素
- 无法找到WebClient
- 使用office 2010 COM的asp.net Web服务
- ASP.NET 5(vNext)Web项目:库冲突从beta4升级到beta6