C# 如何使用Linq根据id连接的另一个列表更新列表中的字段

C# 如何使用Linq根据id连接的另一个列表更新列表中的字段,c#,.net,linq,C#,.net,Linq,我有一个计数器对象列表和一个增量列表。 是否有一种方法可以使用Linq在通过Id连接时使用增量中的数据来更新计数器列表字段 下面是一个简化的代码示例 class Counter { public int Id; public int A; public int B; } class Delta { public int Id; public int ADelta; public int BDelta; } IList<Counter>

我有一个计数器对象列表和一个增量列表。 是否有一种方法可以使用Linq在通过Id连接时使用增量中的数据来更新计数器列表字段

下面是一个简化的代码示例

class Counter
{
    public int Id;
    public int A;
    public int B;
}

class Delta
{
    public int Id;
    public int ADelta;
    public int BDelta;
}

IList<Counter> counters = new List<Counter>()
{
    new Counter{Id=1, A=0, B=5},
    new Counter{Id=2, A=0, B=0},
    new Counter{Id=3, A=5, B=0}
};

IList<Delta> deltas = new List<Delta>()
{
    new Delta(){Id=1, ADelta=5, BDelta = 5},
    new Delta(){Id=3, ADelta=0, BDelta = 10}
};

Linq用于查询,而不是更新现有实例。我建议您为Delta创建字典,然后使用simple foreach更新现有计数器:

var deltasById = deltas.ToDictionary(d => d.Id);

foreach (var counter in counters)
{
    Delta delta;
    if (!deltasById.TryGetValue(counter.Id, out delta))
        continue;

    counter.A += delta.ADelta;
    counter.B += delta.BDelta;
}

如果计数器对应多个增量,该怎么办?在整个应用程序中,每个计数器只有一个增量。
var deltasById = deltas.ToDictionary(d => d.Id);

foreach (var counter in counters)
{
    Delta delta;
    if (!deltasById.TryGetValue(counter.Id, out delta))
        continue;

    counter.A += delta.ADelta;
    counter.B += delta.BDelta;
}
    counters = counters.Select(c =>
                                   {
                                       var delta = deltas.SingleOrDefault(d => d.Id == c.Id);
                                       return new Counter
                                                  {
                                                      Id = c.Id,
                                                      A = c.A + (delta != null ? delta.ADelta : 0),
                                                      B = c.B + (delta != null ? delta.BDelta : 0)
                                                  };
                                   }).ToList();