如何组合2个列表并使用LINQ添加新列表?

时间:2014-08-28 12:09:47

标签: c# linq linq-to-objects

有两个清单。我想基于键(属性)Id组合两个列表,并使用列表2中的值更新此记录。必须添加所有不在列表中的列表项。

我搜索了互联网并找到了有关LINQ加入功能的信息,但我还希望使用LINQ将新记录/项添加到列表中。有谁知道如何做到这一点(使用1 LINQ查询)?

到目前为止我的代码。

public class Item
{
    public string Id { get; set; }
    public string Name { get; set; }
    public string Value { get; set; }
}

[TestFixture]
public class CompareListTest
{
    private List<Item> firstList;

    [SetUp]
    public void SetUp()
    {
        firstList.Add(new Item()
        {
            Id = "1",
            Name = "Name1",
            Value = "NotUpdated1"
        });
    }

    [Test]
    public void ShouldCombineTwoListsAndAddNewOnesUsingIdAsPrimaryKey()
    {
        List<Item> secondList = new List<Item>();
        secondList.Add(new Item()
        {
            Id = "1",
            Name = "NameUpdated1",
            Value = "Updated1"
        });
        secondList.Add(new Item()
        {
            Id = "2",
            Name = "NewOne",
            Value = "New"
        });

        var combineList = new CombineList();
        List<Item> combinedList = combineList.Update(firstList, secondList);
        Assert.That(combinedList.Count, Is.EqualTo(2));
        Assert.That(combinedList.FirstOrDefault(x => x.Id == "1").Value, Is.EqualTo("Updated1"));
        Assert.That(combinedList.FirstOrDefault(x => x.Id == "2").Value, Is.EqualTo("New"));
    }
}

public class CombineList
{
    public List<Item> Update(List<Item> firstList, List<Item> secondList)
    {
        var result = from x in firstList
                     join y in secondList
                     on x.Id equals y.Id
                     select new Item()
                     {
                         Id = y.Id,
                         Name = y.Name,
                         Value = y.Value
                     };
        return result.ToList();
    }
}

2 个答案:

答案 0 :(得分:0)

如果我理解正确,您需要两个列表中的所有项目,但如果有2个具有相同ID的项目,则需要第二个列表中的项目。

我能想到的是:取两个列表的交集(使用第一个列表中的值),然后取第一个列表中的项目减去交叉点中的项目然后取与第二个清单的联合。

var result = (secondList.Union(
    firstList.Except(
        from l in firstList
        join r in secondList
        on l.Id equals r.Id
        select l
    )
)).ToList();

答案 1 :(得分:0)

Dennis_E的方法的另一种选择是:

  1. 查找第一个列表中不在第二个列表中的所有项目
  2. 将第二个列表与步骤1的结果结合起来

    var combinedList = secondList.Concat(     firstList.Where(i1 =&gt;!secondList.Any(i2 =&gt; i2.Id == i1.Id)));

  3. 我选择Concat而不是Union,因为订单无关紧要,Item类未实现Equals

    我选择的!Any略低于All,以提高性能。找到一个匹配项后,无需进一步比较。

    我不知道两者如何比较性能。