C# 将一个对象的两个列表合并为一个

C# 将一个对象的两个列表合并为一个,c#,list,generic-list,C#,List,Generic List,我目前正在开发一个需要这个senario的应用程序 假设我有这个东西 public class ObjectItem { public int Id {get;set;} public int Name {get;set;} public int Sex {get;set;} public int Age {get;set;} public string Complexion {get;set;} } var studentWithAge = new List&l

我目前正在开发一个需要这个senario的应用程序

假设我有这个东西

public class ObjectItem
{
   public int Id {get;set;}
   public int Name {get;set;}
   public int Sex {get;set;}
   public int Age {get;set;}
   public string Complexion {get;set;}
}
var studentWithAge = new List<ObjectItem>
                  {
                    new ObjectItem {Id = 1, Name = "John", Age = 2},
                    new ObjectItem {Id = 2, Name = "Smith", Age = 5},
                    new ObjectItem {Id = 3, Name = "Juliet", Age = 7},
                  };

var studentWithSexAndComplexion = new List<ObjectItem>
                       {
                          new ObjectItem {Id = 1, Name = "John", Sex = "Male", Complexion = "fair"},
                          new ObjectItem {Id = 2, Name = "Smith", Sex = "Male", Complexion = " "},
                          new ObjectItem {Id = 3, Name = "Juliet", Sex = "Female", Complexion = "Blonde"},
                          new ObjectItem {Id = 4, Name = "Shittu", Sex = "Male", Complexion = "fair"},
                       };
如果我们现在有两个这个对象的列表

public class ObjectItem
{
   public int Id {get;set;}
   public int Name {get;set;}
   public int Sex {get;set;}
   public int Age {get;set;}
   public string Complexion {get;set;}
}
var studentWithAge = new List<ObjectItem>
                  {
                    new ObjectItem {Id = 1, Name = "John", Age = 2},
                    new ObjectItem {Id = 2, Name = "Smith", Age = 5},
                    new ObjectItem {Id = 3, Name = "Juliet", Age = 7},
                  };

var studentWithSexAndComplexion = new List<ObjectItem>
                       {
                          new ObjectItem {Id = 1, Name = "John", Sex = "Male", Complexion = "fair"},
                          new ObjectItem {Id = 2, Name = "Smith", Sex = "Male", Complexion = " "},
                          new ObjectItem {Id = 3, Name = "Juliet", Sex = "Female", Complexion = "Blonde"},
                          new ObjectItem {Id = 4, Name = "Shittu", Sex = "Male", Complexion = "fair"},
                       };
var studentWithAge=新列表
{
新对象项{Id=1,Name=“John”,Age=2},
新对象项{Id=2,Name=“Smith”,Age=5},
新对象{Id=3,Name=“Juliet”,Age=7},
};
var studentWithSexAndComplexion=新列表
{
新对象{Id=1,Name=“John”,Sex=“Male”,肤色=“fair”},
新对象{Id=2,Name=“Smith”,Sex=“Male”,肤色=”“},
新对象{Id=3,Name=“朱丽叶”,Sex=“女性”,肤色=“金发碧眼”},
新对象{Id=4,Name=“Shittu”,Sex=“Male”,肤色=“fair”},
};
我想把这两个列表合并成一个。最终结果应该是这样的

var CompleteStudentData=new List<ObjectItem>
{
   new ObjectItem{Id=1,Name="John",Sex="Male", Complexion="fair",Age=2},
   new ObjectItem{Id=2,Name="Smith",Sex="Male", Complexion=" ", Age=5},
   new ObjectItem{Id=3,Name="Juliet",Sex="Female", Complexion="Blonde", Age=7},
   new ObjectItem{Id=4,Name="Shittu",Sex="Male", Complexion="fair", Age=0},
}
var CompleteStudentData=新列表
{
新对象{Id=1,Name=“John”,Sex=“Male”,肤色=“fair”,年龄=2},
新目标项{Id=2,Name=“Smith”,Sex=“Male”,肤色=“”,年龄=5},
新对象{Id=3,Name=“朱丽叶”,Sex=“女性”,肤色=“金发”,年龄=7},
新对象{Id=4,Name=“Shittu”,Sex=“Male”,肤色=“fair”,年龄=0},
}
我如何做到这一点?使用
Union
合并两个列表不会产生所需的结果。谢谢你的帮助

var result = StudentWithAge.Join(StudentWithSexAndComplexion, 
                                 sa => sa.Id,
                                 ssc => ssc.Id,
                                 (sa, ssc) => new ObjectItem
                                 {
                                    Id = sa.Id,
                                    Name = sa.Name, 
                                    Age = sa.Age, 
                                    Sex = ssc.Sex, 
                                    Complexion = ssc.Complexion
                                 }).ToList();
或者,避免创建新对象:

var result = StudentWithAge.Join(StudentWithSexAndComplexion, 
                                 sa => sa.Id,
                                 ssc => ssc.Id,
                                 (sa, ssc) => 
                                 { 
                                    sa.Sex = ssc.Sex; 
                                    sa.Complexion = ssc.Complexion; 
                                    return sa;
                                 }).ToList();
如果您想添加仅出现在第二个列表中的学生,请同时:

result.AddRange(StudentWithSexAndComplexion.Where(ssc => !StudentWithAge.Any(sa => sa.Id == ssc.Id)));

.Net有一个连接集合的函数:

var concatenatedCollection=StudentWithAge.Concat(studentwithsexandcomposion.ToList()

var StudentWithAge=新列表()
{
新对象项{Id=1,Name=“John”,Age=2},
新对象项{Id=2,Name=“Smith”,Age=5},
新对象{Id=3,Name=“Juliet”,Age=7},
};
var StudentWithSexAndComplexion=新列表()
{
新对象{Id=1,Name=“John”,Sex=“Male”,肤色=“fair”},
新对象{Id=2,Name=“Smith”,Sex=“Male”,肤色=”“},
新对象{Id=3,Name=“朱丽叶”,Sex=“女性”,肤色=“金发碧眼”},
新对象{Id=4,Name=“Shittu”,Sex=“Male”,肤色=“fair”},
};
var concatenatedCollection=StudentWithAge.Concat(studentwithsexandcomposion.ToList();

由于您的集合可能不会有1对1的通信,因此您必须进行完全的外部联接。看看你是如何用这种方式创作的

这里有一种方法可以得到类似的结果

收集两个集合中的所有键(ID),然后与每个集合执行左联接,然后合并结果

var ids = studentWithAge.Select(s => s.Id)
    .Union(studentWithSexAndComplexion.Select(s => s.Id));
var query =
    from id in ids
    from sa in studentWithAge
                    .Where(sa => sa.Id == id)
                    .DefaultIfEmpty(new ObjectItem { Id = id })
    from ssc in studentWithSexAndComplexion
                    .Where(ssc => ssc.Id == id)
                    .DefaultIfEmpty(new ObjectItem { Id = id })
    select new ObjectItem
    {
        Id = id,
        Name = sa.Name ?? ssc.Name,
        Sex = ssc.Sex,
        Age = sa.Age,
        Complexion = ssc.Complexion,
    };

这看起来像外部联接。由于ObjectItem的性质和两个列表的内容,最好按名称而不是Id联接。这个答案完美地解决了我的问题。所以我已经标记了这是正确的答案。我对查询做了轻微的调整,查询语法中的左连接是不必要的复杂。我用一个等价的查询替换了它。非常感谢。我真的很感激你的帮助help@frenchie:我尝试了你的答案,但它从列表中漏掉了ID=4的“ObjectItem”。这就是我不接受它作为正确答案的原因。不过,我很感谢你的帮助。啊,是的,没有看到列表大小不一!