使用LINQ合并2个列表并汇总多个属性
我有一个包含以下属性的类:
public class SomeClass() { public Int32 ObjectId1 {get;set;} public Int32 ObjectId2 {get;set;} public Int32 ActiveThickeness {get;set;} public Int32 ActiveFilterThickness {get;set;} }
我还有2个列表:
List A List B
列表A有数据:
| ObjectId1 | ObjectId2 | ActiveThickness | ActiveFilterThickness | ------------------------------------------------------------------- | 1 | 3 | 50 | 0 | ------------------------------------------------------------------ | 1 | 2 | 400 | 0 | ------------------------------------------------------------------- | 4 | 603 | 27 | 0 | -------------------------------------------------------------------
清单B有数据:
| ObjectId1 | ObjectId2 | ActiveThickness | ActiveFilterThickness | ------------------------------------------------------------------- | 1 | 3 | 0 | 13671 | ------------------------------------------------------------------ | 1 | 2 | 0 | 572 | ------------------------------------------------------------------- | 29 | 11 | 0 | 4283 | -------------------------------------------------------------------
我想将A和B(如果可能,使用LINQ)合并到SomeCalss的List C中,其中包含如下数据:
| ObjectId1 | ObjectId2 | ActiveThickness | ActiveFilterThickness | ------------------------------------------------------------------- | 1 | 3 | 50 | 13671 | ------------------------------------------------------------------ | 1 | 2 | 400 | 572 | ------------------------------------------------------------------- | 29 | 11 | 0 | 4283 | ------------------------------------------------------------------- | 4 | 603 | 27 | 0 | -------------------------------------------------------------------
我怎样才能做到这一点?
使用GroupBy
对公共对象进行分组,使用Sum
对所需属性求和
var ab = A.Concat(B).GroupBy(x => new { x.ObjectId1, x.ObjectId2 }); var result = ab.Select(x => new SomeClass { ObjectId1 = x.Key.ObjectId1, ObjectId2 = x.Key.ObjectId2, ActiveFilterThickness = x.Sum(i => i.ActiveFilterThickness), ActiveThickeness = x.Sum(i => i.ActiveThickeness) });
请参阅LINQ – 完全外部加入 (SO)。
通过左外连接和右外连接,然后取两者的结合,你应该得到你正在寻找的东西。
var leftOuterJoin = from someclass1 in A join someclass2 in B on someclass1.ObjectID2 equals someclass2.ObjectID2 into temp from item in temp.DefaultIfEmpty(new SomeClass(){ objectID1 = someclass1.objectID1, ... }) select new SomeClass() { ... }; var rightOuterJoin = from someclass2 in B join someclass1 in A on someclass1.ObjectID2 equals someclass2.ObjectID2 into temp from item in temp.DefaultIfEmpty(new SomeClass(){ objectID1 = someclass1.objectID1, ... }) select new SomeClass() { ... }; var fullOuterJoin = leftOuterJoin.Union(rightOuterJoin);