基于键更新列表对象 - LINQ

时间:2011-03-13 22:57:01

标签: c# linq-to-objects

这是我的List对象

List<MemObject>
                   {
                       new MemObject
                           {Serial = 1, ErrorCode = "ABC", ModifedAt = new DateTime(2011, 12, 15, 10, 10, 30)},
                       new MemObject
                           {Serial = 1, ErrorCode = "ABD", ModifedAt = new DateTime(2011, 12, 15, 10, 10, 30)},
                       new MemObject
                           {Serial = 1, ErrorCode = "ABC", ModifedAt = new DateTime(2011, 12, 15, 10, 10, 30)},
                       new MemObject
                           {Serial = 1, ErrorCode = "ABC", ModifedAt = new DateTime(2011, 12, 15, 10, 10, 30)},
                   };

我希望通过为具有相同Serial,ErrorCode的每个2,3,... n记录增加一秒的时间来更新ModifiedAt字段。

如何在linq中完成。

4 个答案:

答案 0 :(得分:1)

这与我能得到的单个linq语句非常接近。它确实有用。

    public void IncrementTime(int serial, string errorCode)
    {
        var matchObjects = _memObjects.Where(x => x.Serial == serial && x.ErrorCode == errorCode).ToList();

        matchObjects.ForEach(x => x.ModifedAt = x.ModifedAt.AddSeconds(
                                    matchObjects.Count(y => matchObjects.IndexOf(y) < matchObjects.IndexOf(x))
                             ));
    }

答案 1 :(得分:1)

这将更新每个ModifiedAt记录。如果您不想在记录计数中包含更新的对象,则可能必须执行Count(...) - 1。

memObjects.ForEach(x => x.ModifiedAt.AddSeconds(memObjects.Count(y => y.Serial == x.Serial && y.ErrorCode == x.ErrorCode)));

答案 2 :(得分:0)

也许是这样的事情?

public void IncrementTime(int serial, string errorCode)
{
    _memObjects.Where(x => x.Serial == serial && x.errorCode == errorCode)
        .ToList()
        .ForEach(x => x.ModifiedAt = x.ModifiedAt.Add(new TimeSpan(0, 0, 1)));
}

答案 3 :(得分:0)

LINQ在这里不会真的帮到你。它并不意味着用于更新集合,而是用于搜索集合。你不应该期待更多。如果使用得当,您可以根据自己的要求对项目进行分组并更新项目。

// group the MemObjects by Serial and ErrorCode that has more than 1 occurrences
var query = list.GroupBy(mo => new { mo.Serial, mo.ErrorCode })
                //.Where(g => g.Count() > 1); // O(n)
                .Where(g => g.Skip(1).Any()); // O(1)

// make the updates
foreach (var group in query)
{
    int i = 1;
    foreach (var mo in group)
    {
        mo.ModifedAt += TimeSpan.FromSeconds(i++);
    }
}