使用linq查询获取最后一项

时间:2018-03-23 06:11:48

标签: c# entity-framework linq

我有一个使用实体框架从数据库获取的列表。

var list = context.Items;

列表结果是这样的。

var list = new List<Item>{
    new Item { id=1, operation="write", date="23.03.2018 08:25:45" },
    new Item { id=1, operation="read", date="23.03.2018 09:40:15" },
    new Item { id=1, operation="read", date="23.03.2018 10:15:17" },
    new Item { id=1, operation="read", date="23.03.2018 11:46:39" }
}

我想通过操作和上次日期缩小此列表。

var min = new List<Item>{
    new Item { id=1, operation="write", date="23.03.2018 08:25:45" },
    new Item { id=1, operation="read", date="23.03.2018 11:46:39" }
}

我正在进行最后一次“write”操作和最后一次“read”项目。

5 个答案:

答案 0 :(得分:0)

您可以尝试以下操作。只需按操作分组,然后选择每个组中的最后一个日期。

var lastItems = list.GroupBy(p => p.operation).Select(grp => new
        {
            grp.Key,
            lastOperation = grp.OrderByDescending(p => Convert.ToDateTime(p.date)).First()
        }).Select(p=> p.lastOperation);

但是,如果您的日期字段包含不同的时间格式,则可能无法转换为DateTime。

并且您需要确保将日期字段转换为DateTime,否则您可能会按字符串获得不同的排序。

编辑:以下内容与较少的输入相同:

var lastItems = list.GroupBy(p => p.operation).Select(grp => 
            grp.OrderByDescending(p => Convert.ToDateTime(p.date)).First());

答案 1 :(得分:0)

我使用了根据日期对行进行编号的概念,然后对其进行过滤。类似的东西:

var groups = list.GroupBy(x => x.operation)
               .SelectMany(g =>
                   g.OrderByDescending(i => i.date).Select((j, i) => new { j.id, j.operation,j.date, rn = i + 1 })
               );

var data = groups.Where(i => i.rn == 1).ToList();

答案 2 :(得分:0)

好像你需要从列表中获得不同的价值,然后你需要获得最新日期的第一项

List<Item> list = context.Items
                  .GroupBy(a => a.operation)
                  .Select(g => g.OrderByDescending(p => Convert.ToDateTime(p.date)).First())
                  .ToList();

你需要执行group by on operation一旦完成,你应该从每个小组中取出第一个项目,但要按照日期采取最新的日期,你需要在日期进行降序,这将使最新的日期记录首次重新开始并且你只需要在它上面应用第一个功能。

答案 3 :(得分:0)

您可以借助以下代码实现它

var result = list.GroupBy(x => x.operation)
                 .Select(x => x.OrderByDescending(y => Convert.ToDateTime(y.date)).FirstOrDefault())
                 .ToList();

答案 4 :(得分:0)

由于Max比排序快得多,所以请使用Max。很遗憾,您的date字段不是DateTime,因此需要进行转换。我首先进行了转换,因此在过滤时我不必进行两次转换。我也没有假设每个操作最多只有一个date,如果只需要你可以添加First。我保留并最后返回原来的Item

var min = from item in list
          select new { item, date = DateTime.Parse(item.date) } into newitem
          group newitem by newitem.item.operation into itemgroup
          let maxdate = itemgroup.Max(i => i.date)
          from item in itemgroup
          where item.date == maxdate
          select item.item;

注意:.Net Core可能会处理OrderBy.First的情况而不进行排序。