根据用户ID选择列表中的最大日期

时间:2013-12-23 11:26:17

标签: linq list group-by max

public class Person
{
    public int Id {get;set;}
    public int PersonId {get;set;}
    public string University {get;set;}
    public string Department {get;set;}
    public DateTime GraduatedDate {get;set;}
}

List<Person> list = new List<Person>();
list.Add(new Person { 1, 1, "Shota Rustavelli University", "Computer Science BS", "10.12.2005" });
list.Add(new Person { 2, 1, "Shota Rustavelli University", "Computer Science MS", "10.12.2005" });
list.Add(new Person { 3, 2, "Tblisi State University", "Mathematics BS", "10.12.2004" });
list.Add(new Person { 4, 3, "Shota Rustavelli University", "Economics BS", "10.12.2006" });
list.Add(new Person { 5, 3, "Tblisi State University", "Economics MS", "10.12.2006" });
list.Add(new Person { 6, 1, "Georgian Technical University", "Mathemetics Phd", "10.12.2009" });



foreach(var item in (list.GroupBy(m=> new{m.PersonId,m.University,m.Department})).Max(m=>m.GraduatedDate))
{
    item.PersonId
    item.University
    item.Department
}

我是如何根据PersonId使用以下结构获得上一个大学和部门。我曾尝试使用LINQ GroupBy和Max,但我得到了错误。

2 个答案:

答案 0 :(得分:2)

Max(m=>m.GraduatedDate)会为您带来:GraduatedDate在集合中的最大值。在您的情况下,它不会编译,因为您将它应用于没有GraduatedDate属性的项目集合。

为了获得每人的最后一次毕业,您可以使用以下LINQ查询:

    var results = 
        list
        .GroupBy(m => m.PersonId)
        .Select(g => new {
            PersonId = g.Key,
            LastGraduation = g.OrderByDescending(p => p.GraduatedDate).First()
        });

结果可以像这样显示,例如:

    foreach(var r in results){
        Console.WriteLine("{0}, {1}, {2}", 
            r.PersonId,
            r.LastGraduation.University,
            r.LastGraduation.Department);
    }

以下是一个ideone代码段,其中显示了此版本的运行版本:http://ideone.com/em4Ygq

请注意,我已将GraduatedDate更改为string,以便更好地匹配初始化列表的方式。我应该声明为DateTime并相应地进行初始化。

答案 1 :(得分:1)

虽然您可以使用GroupBy和Max返回最新的人员条目,但使用MoreLINQ的MaxBy运算符返回具有最大谓词的元素会更容易且更快捷:

IEnumerable<Person> personEntries=list.GroupBy(p => p.PersonId)
            .Select(g => g.MaxBy(p => p.GraduatedDate));

您可以将MoreLINQ库添加为single NuGet package,或者只添加所需运算符的源代码,例如MaxBy

这些运算符比GroupBy更快并且排序的原因是MaxBy / MinBy运算符不对列表的元素进行排序,而是简单地遍历所有项目,仅保留对它们遇到的最大/最小项目的引用。这比排序要快得多。

在PLINQ场景中,MaxBy / MinBy是必不可少的,因为排序会引入锁定和同步,这可能会使您的PLINQ查询运行速度比顺序版本慢。