【问题标题】:Select values with max date for each ID [duplicate]为每个 ID 选择具有最大日期的值 [重复]
【发布时间】:2017-08-29 12:27:56
【问题描述】:

这是“历史”表

id  value   date
1   1   01/01/2017 20:20:20
1   2   02/01/2017 20:20:20
1   3   03/01/2017 20:20:20
2   5   01/01/2017 20:20:20
2   6   02/01/2017 20:20:20

如何使用 linq 为每个 id 选择最大值

context.History
    .GroupBy(x => x.id) ??
    .SelectOnlyWithMax(z => z.date) ??

结果只有两个对象

id  value   date
1   3   03/01/2017 20:20:20
2   6   02/01/2017 20:20:20

【问题讨论】:

  • 请展示您尝试过的内容,可能以GroupBy开头...
  • 您想要什么结果,IdValue,还是日期最高的整行?
  • 另外,实体框架需要这个吗?如果是这样,它可能会限制一些可能的答案。

标签: c# linq


【解决方案1】:

如果您想要每个Id 具有最高日期的整行,您可以使用以下代码(使用LinqPad 编写)。如果您只想要Id,您可以使用@BurnsBA 的答案,因为它会稍微高效一些。

void Main()
{
    var data = new List<Record>
    {
        new Record(){Id=1, Value=1, Date=new DateTime(2017,1,1)},
        new Record(){Id=1, Value=2, Date=new DateTime(2017,2,1)},
        new Record(){Id=1, Value=3, Date=new DateTime(2017,3,1)},
        new Record(){Id=2, Value=5, Date=new DateTime(2017,1,1)},
        new Record(){Id=2, Value=6, Date=new DateTime(2017,2,1)},
    };


    var query = data.GroupBy(d => d.Id)
                    .SelectMany(g => g.OrderByDescending(d => d.Date)
                                      .Take(1));
    query.Dump();
}

public class Record
{
    public int Id { get; set; }
    public int Value { get; set; }
    public DateTime Date { get; set; }
}

结果:

首先它按Id分组,然后按Date降序对组内的项目进行排序,并返回第一个SelectMany然后展平列表。

【讨论】:

    【解决方案2】:
    public class History
    {
        public int id { get; set; }
        public int value { get; set; }
        public DateTime date { get; set; }
    }
    
    // setup:
    var values = new List<History>();
    values.Add(new History() { id = 1, value = 1, date = DateTime.Parse("01/01/2017 20:20:20") });
    values.Add(new History() { id = 1, value = 2, date = DateTime.Parse("02/01/2017 20:20:20") });
    values.Add(new History() { id = 1, value = 3, date = DateTime.Parse("03/01/2017 20:20:20") });
    values.Add(new History() { id = 2, value = 5, date = DateTime.Parse("01/01/2017 20:20:20") });
    values.Add(new History() { id = 2, value = 6, date = DateTime.Parse("02/01/2017 20:20:20") });
    
    // result :
    values.GroupBy(
        x => x.id, 
        y => y.date,
        // Below, dates will be enumerable
        (id, dates) => new { id = id, date = dates.Max() }
    )
    
    // returns enumerable collection of anonymous type:
    {
        { id = 1, date = [3/1/2017 8:20:20 PM] }, 
        { id = 2, date = [2/1/2017 8:20:20 PM] }
    }
    

    【讨论】:

      【解决方案3】:

      我建议MoreLINQMaxBy函数,即:

      context.History.GroupBy( x => x.id ).Select( x => x.MaxBy( y => y.date) )
      

      【讨论】:

      • 这个实体框架兼容吗?这个问题没有用 EF 标记,但从他们通过名为context 的变量查询的方式,以及他们提到“表”的事实,让我认为他们需要支持实体框架的东西。根据对MaxBy 来源的快速扫描,它可能不是。
      猜你喜欢
      • 2019-12-07
      • 1970-01-01
      • 2016-12-22
      • 1970-01-01
      • 2017-04-17
      • 1970-01-01
      • 1970-01-01
      • 2020-03-06
      • 2016-09-25
      相关资源
      最近更新 更多