我有这堂课:
public class tempClass
{
public int myKey { get; set; }
public int total { get; set; }
}
分组和总和的代码:
var list = new List<tempClass>();
list.Add(new tempClass { myKey = 1, total = 1 });
list.Add(new tempClass { myKey = 1, total = 2 });
list.Add(new tempClass { myKey = 2, total = 3 });
list.Add(new tempClass { myKey = 2, total = 4 });
list = list
.Select(w => new tempClass { myKey = w.myKey, total = w.total })
.GroupBy(x => new tempClass { myKey = x.myKey })
.Select(y => new tempClass { myKey = y.Key.myKey, total = y.Sum(z => z.total) })
.ToList();
list
之后GroupBy
计数仍然是4。
以下代码的结果相同:
list = list
.GroupBy(x => new tempClass { myKey = x.myKey })
.Select(y => new tempClass { myKey = y.Key.myKey, total = y.Sum(z => z.total) })
.ToList();
答案 0 :(得分:4)
原因是您按照不会覆盖Equals
和GetHashCode
的类进行分组。然后使用System.Object
的实现,它只是比较引用。由于所有都是不同的引用,因此每个实例都会得到一个组。
您可以按此媒体资源进行分组,或覆盖Equals
和GetHashCode
来比较此媒体资源:
list = list
.Select(w => new tempClass { myKey = w.myKey, total = w.total })
.GroupBy(x => x.myKey)
.Select(y => new tempClass { myKey = y.Key, total = y.Sum(z => z.total) })
.ToList();
答案 1 :(得分:2)
您不需要两条Select
行,一条就足够了。在GroupBy
内,只需选择你的密钥,不要在那里创建一个新的对象:
list = list
.GroupBy(x => x.myKey)
.Select(y => new tempClass { myKey = y.Key, total = y.Sum(z => z.total) })
.ToList();
这是声明性查询语法版本:
list = (from x in list
group x by x.myKey into g
select new tempClass { myKey = g.Key, total = g.Sum(z => z.total) }).ToList();
答案 2 :(得分:1)
我的,你在LINQ语句中创建了很多新的TempClass对象,不是吗?
您没有得到正确结果的原因是您的GroupBy不会使用相等的TempClass.MyKey创建具有相同TempClass的TempClass对象组。
TempClass的默认EqualityComparer声明两个TempClass对象相等(如果它们是同一个对象),从而使两个TempClass对象不相等,即使它们具有相同的值。
您的查询应该是:
var result = list
.GroupBy(listItem => listItem.MyKey) // make groups with equal MyKey
.Select(group => new // from every group make one new item
{
Key = group.Key, // with key the common MyKey in the group
GrandTotal = group.Sum(groupItem => groupItem.Total);
// and value the sum of all Total values in the group
});
我选择不将最终结果项目作为一系列TempClasses,因为我不确定您是否会将具有此GrandTotal的项目视为TempClass对象。但如果你愿意,你可以改变最终的选择:
.Select(group => new TempKey()
{
Key = group.Key,
Total = group.Sum(groupItem => groupItem.Total);
});