选择每个ID的最大日期值

时间:2017-08-29 12:27:56

标签: c# linq

这是表"历史"

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

3 个答案:

答案 0 :(得分:5)

如果您希望每个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; }
}

结果:

enter image description here

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

答案 1 :(得分:1)

我建议使用MoreLINQMaxBy函数,即:

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

答案 2 :(得分:1)

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] }
}