Linq Group By,跳过1,其中跳过的1是最近的

时间:2015-06-25 14:11:26

标签: c# linq unit-testing tdd

我有一个存储在事件列表中的对象数据集(这些变量都是在类级别之前声明的):

    [SetUp]
    public void Setup()
    {
        eventLogObj = new EventLogObj();

        event1 = new EventLogObj() { RecordId = 1, TableKey = "PERSON_CODE=1", Status = "S", EventTime = Convert.ToDateTime("2013-07-15 14:00:00") };
        event2 = new EventLogObj() { RecordId = 2, TableKey = "PERSON_CODE=2", Status = "S", EventTime = Convert.ToDateTime("2013-07-15 13:00:00") };
        event3 = new EventLogObj() { RecordId = 3, TableKey = "PERSON_CODE=3", Status = "S", EventTime = Convert.ToDateTime("2013-07-15 13:00:00") };
        event4 = new EventLogObj() { RecordId = 4, TableKey = "PERSON_CODE=2", Status = "S", EventTime = Convert.ToDateTime("2013-07-15 14:00:00") };
        event5 = new EventLogObj() { RecordId = 5, TableKey = "PERSON_CODE=1", Status = "S", EventTime = Convert.ToDateTime("2013-07-15 13:00:00") };

        events = new List<EventLogObj>() { event1, event2, event3, event4, event5 };
    }

我最初只是提取重复项 - 有效(下图)

    [Test]
    public void StoreOnlyDuplicateDetailsFromRowsIntoCollection()
    {
        var duplicates = events.GroupBy(s => s.TableKey)
            .SelectMany(grp => grp.Skip(1)).ToList();

        Assert.AreEqual(2, duplicates.Count);
    }

但是,现在我想提取具有最低日期的重复项,并且我不太确定如何调整我设置的linq查询。

这是我到目前为止所做的,但它失败了。

如果您想知道duplicates2是什么,那么尝试实现这一点的尝试失败了:LINQ: Group by aggregate but still get information from the most recent row?

    [Test]
    public void pickDuplicateEventWithLeastDate()
    {
        var duplicates = events
            //.OrderBy(e => e.EventTime)
            .GroupBy(s => s.TableKey)
            .SelectMany(grp => grp.Skip(1))
            .ToList();

        var duplicates2 = from res in events
                          group res by res.TableKey into g
                          select new
                          {
                              Count = g.Count(),
                              MemberID = g.Key,
                              MostRecent = g.OrderByDescending(x => x.EventTime)
                              .First()
                          };

        Assert.AreEqual(2, duplicates.Count);
        var e1 = duplicates[0];
        var e2 = duplicates[1];

        Assert.AreEqual(e1.EventTime, Convert.ToDateTime("2013-07-15 13:00:00"));
        Assert.AreEqual(e2.EventTime, Convert.ToDateTime("2013-07-15 13:00:00"));
    }

如果您想在不需要在Visual Studio中设置接口,类等的情况下进行尝试,请参阅此处https://dotnetfiddle.net/YYoSfM并进行操作。基本上,如果测试通过,您应该在控制台窗口中得不到任何内容。

1 个答案:

答案 0 :(得分:2)

您正在跳过第一项,因此必须是具有最高日期的项目。为此,您需要使用属于OrderByDescending之前的SelectMany内的Skip

 var duplicates = events
            .GroupBy(s => s.TableKey)
            .SelectMany(grp => grp.OrderByDescending(e => e.EventTime)
                                  .Skip(1))
            .ToList();

如果您希望其他重复项按升序排序,只需在.OrderBy(e => e.EventTime)之后添加Skip

哦,你的测试数据是假的。 PERSON_CODE=1的第一个数据项是2013-07-1 3 ,但应该在2013-07-1 5 以通过测试套件。