繁体   English   中英

Linq 按对象分组然后选择

[英]Linq Group By Object Then Select

我希望按LeagueIdDate对记录进行LeagueId 然后按日期排序 desc ,然后选择第一次出现的不同LeagueId 到目前为止,我有类似的东西,但我不知道如何在第一次出现不同的LeagueId选择统计数据。

var stats =
    _statsRepository.FindBy(x => x.Active)
         .GroupBy(x => new { x.LeagueId, x.Date })
         .OrderByDescending(x => x.Key.Date)
         .SelectMany(x => x);

这几乎是获取每个联赛最新统计数据的一种方式。 所以联赛 1 = 12/02/2017,联赛 2 可能是 02/02/17。 <---忽略这一点,可能会产生误导。

有许多统计记录发生在联赛中的某个日期。 因此,对于每个联赛的特定日期,都会有多个统计数据。

Record 1:
09/01/14,
Jim,
4 Goals,
League 1

Record 2:
13/01/14,
Jack,
2 Goals,
League 1

Record 3:
13/01/14,
James,
2 Goals,
League 1

Record 4:
15/01/14,
Hannah,
2 Goals,
League 2

Record 5:
15/01/14,
Harmony,
1 Goal,
League 2

Record 6:
10/01/14,
Alision,
3 Goals,
League 2

应该选择的记录是

Record 2:
13/01/14,
Jack,
2 Goals,
League 1

Record 3:
13/01/14,
James,
2 Goals,
League 1

Record 4:
15/01/14,
Hannah,
2 Goals,
League 2

Record 5:
15/01/14,
Harmony,
1 Goal,
League 2

说明:对于联赛 1,记录 2 和 3 出现在记录 1 之后,因此它们都被选中。 对于联赛 2,应选择记录 4 和 5,因为它们是最新日期。

使用最新更新,您需要按LeagueId进行分组,并简单地从每个分组中获取所有记录,其中Date等于分组中的最大Date

var stats = _statsRepository.FindBy(x => x.Active)
    .GroupBy(x => x.LeagueId)  
    .SelectMany(g => g.Where(x => x.Date == g.Max(y => y.Date));

获得相同结果的另一种方法是使用!Any (SQL NOT EXISTS ) 构造:

var baseStats = _statsRepository.FindBy(x => x.Active);
var stats = baseStats
    .Where(x => !baseStats.Any(y => y.LeagueId == x.LeagueId && y.Date > x.Date));

我假设您使用IQueryable s(即不是LINQ to Objects在这些事情上很重要),因此不需要像中间Select s 这样的优化。

您想按联赛分组,然后为每个联赛取组中最近的日期

var stats = _statsRepository.FindBy(x => x.Active)
            .GroupBy(x => new { x.LeagueId, x.Date })
            .GroupBy(g => g.Key.LeagueId)
            .Select(gg => new { LeagueId = gg.Key, Stats = gg.OrderByDescending(g => g.Key.Date).First().ToList() })
            .ToList();

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM