简化 group、order 和 select top 1 的 Linq 语法

To simplify the Linq syntax for group, order and select top 1

我在 Deal class 中有几个数据,如下所示:

public class Deal
{
 public int Id {get;set;}
 public int SiteEdition {get;set;}
 public DateTime Date {get;set;}
}

我尝试按 "Id" 和 "SiteEdition" 对它们进行分组;在每个组中,按日期排序,select 前 1 个数据。 我的代码是这样的:

    List<Deal> dealList = new List<Deal>();
    dealList.Add(new Deal(){Id=123, SiteEdition =1, Date = new DateTime(2017,6,1) });
    dealList.Add(new Deal(){Id=123, SiteEdition =1 , Date = new DateTime(2017,6,5) });
    dealList.Add(new Deal(){Id=123, SiteEdition =2 , Date = new DateTime(2017,6,9) });
    dealList.Add(new Deal(){Id=445, SiteEdition =1 , Date = new DateTime(2017,6,14) });
    dealList.Add(new Deal(){Id=445, SiteEdition =1 , Date = new DateTime(2017,6,19) });
    dealList.Add(new Deal(){Id=445, SiteEdition =2 , Date = new DateTime(2017,6,22) });
    dealList.Add(new Deal(){Id=445, SiteEdition =2 , Date = new DateTime(2017,6,25) });
    dealList.Add(new Deal(){Id=445, SiteEdition =3 , Date = new DateTime(2017,6,27) });
    dealList.Add(new Deal(){Id=445, SiteEdition =3 , Date = new DateTime(2017,6,29) });



    List<Deal> finalList = dealList.GroupBy(s=>new{s.Id,s.SiteEdition}).Select(y => new Deal{Id=y.OrderByDescending(m=>m.Date).First().Id, SiteEdition = y.OrderByDescending(m=>m.Date).First().SiteEdition, Date = y.OrderByDescending(m=>m.Date).First().Date}).ToList();
    foreach(var item in finalList)
    {
      Console.WriteLine("Id: " + item.Id + "; SiteEdition: " + item.SiteEdition + " ;DateTime: " + item.Date);
    }

它工作正常,但 linq 语法看起来很难看,尤其是 "y.OrderByDescending(m=>m.Date).First()" 的部分......

有什么方法可以简化这个语法吗?

您不需要创建 Deal 的新实例。只是 return 一个你已经在组中的人。

您可以利用 GroupBy 保留源序列在组内的顺序这一事实 - 只需对序列进行一次排序并且 select 每个组中的第一个项目

dealList.OrderByDescending(d => d.Date)
        .GroupBy(d => new { d.Id, d.SiteEdition })
        .Select(g => g.First())
        .ToList()

或者您可以分别对每个组进行排序

dealList.GroupBy(d => new { d.Id, d.SiteEdition })
        .Select(g => g.OrderByDescending(d => d.Date).First())
        .ToList()