以下为一个合并学生分数的示例数据,依据主键统计各个学生的总分数
IList<Student>students=newList<Student>(); students.Add(newStudent(){Id=3,Score=99,Name="语文"}); students.Add(newStudent(){Id=5,Score=87,Name="语文"}); students.Add(newStudent(){Id=3,Score=95,Name="数学"}); students.Add(newStudent(){Id=3,Score=97,Name="外语"}); students.Add(newStudent(){Id=5,Score=90,Name="外语"}); students.Add(newStudent(){Id=2,Score=96,Name="语文"}); students.Add(newStudent(){Id=5,Score=88,Name="数学"}); students.Add(newStudent(){Id=2,Score=97,Name="数学"});
拿到这种数据,如果要将数据合并,常规的做法就是通过遍历实现,代码简单也容易理解
Dictionary<int,int>query=newDictionary<int,int>();foreach(varelementinstudents){if(query.ContainsKey(element.Id)){ query[element.Id]+=element.Score; }else{ query.Add(element.Id,element.Score); } }
不考虑代码行数为工作绩效的情况下,可以通过Linq或扩展方法一行优雅的搞定
varquery=(fromsinstudents groupsbys.Idintongselectng).ToDictionary(d=>d.Key,d=>d.Sum(s=>s.Score));
varquery=students.GroupBy(g=>g.Id).ToDictionary(d=>d.Key,d=>d.Sum(s=>s.Score));
通过GroupBy过滤主键去掉重复项,避免ToDictionary时重复主键异常,当然上面都是简单的转换,下面可以实现稍微点复杂的去重合并
varquery=students.GroupBy(g=>g.Id).Select(s=>newStudent{Id=s.Key,Score=s.Sum(n=>n.Score),Name=string.Join(",",s.Select(t=>t.Name))});
当然太复杂的合并其实不推荐纯扩展方法来实现,很容易造成语法太过复杂维护成本高,对于复杂的合并还是推荐通过Linq和扩展方法组合自定义函数来实现。