【问题标题】:C# Linq - EF, select grouped data having the max valueC# Linq - EF,选择具有最大值的分组数据
【发布时间】:2021-09-04 17:45:33
【问题描述】:

我有一个多对多表,用于存储 UserId、SectionId、Attempt、Qualification 和时间戳。因此,用户可以按部分进行 N 次尝试,但是当我评估每个部分时,只需要在尝试是最大值的地方取值。 我尝试通过 Attempt 使用键 UserId 和 SectionId ordering desc 进行连接

 var result = await (from exam in db.exams
                            join section in db.sections on exam.SectionId equals section.Id
                            join groupedTable in (from exam2 in db.exams
                                                  group exam2 by new { UserId = exam2.UserId, SectionId = exam2.SectionId, Attempt = exam2.Attempt } into grouped
                                                  select new { UserId = grouped.Key.UserId, SectionId = grouped.Key.SectionId, LastAttempt = grouped.Max(x => x.Attempt) })
                                                  .OrderByDescending(x => x.LastAttempt)
                                                  .Select(x => new
                                                  {
                                                     UserId = x.UserId,
                                                     SectionId = x.SectionId,
                                                     LastAttempt = x.LastAttempt
                                                  })

                            on new { UserId = exam.UserId, SectionId = section.Id }
                            equals new { UserId = groupedTable.UserId, SectionId = groupedTable.SectionId }
                            select exam)
                            .Distinct()
                            .ToListAsync();

也试过了

   var result = await (from exam in db.exams
                            join section in db.sections on exam.SectionId equals section.Id
                            select new
                            {
                                UserId = exam.UserId,
                                SectionId = exam.SectionId,
                                Attempt = exam.Attempt
                            })
                            .GroupBy(x => new
                            {
                                x.UserId,
                                x.SectionId,
                                x.Attempt
                            })
                            .Select(x => new
                            {
                                UserId = x.Key.UserId,
                                SectionId = x.Key.SectionId,
                                Attempt = x.Max(x => x.Attempt)
                            })
                            .ToListAsync();
   

但结果是一样的:

{ UserId = {e56e13b6-28e5-46b2-bd78-f975fd96e1a7}, SectionId = 8, Attempt = 1 }
{ UserId = {e56e13b6-28e5-46b2-bd78-f975fd96e1a7}, SectionId = 10, Attempt = 1 }
{ UserId = {e56e13b6-28e5-46b2-bd78-f975fd96e1a7}, SectionId = 9, Attempt = 1 }
{ UserId = {e56e13b6-28e5-46b2-bd78-f975fd96e1a7}, SectionId = 10, Attempt = 2 }

在这个例子中,我需要排除 SectionId = 10 和 Attempt = 1

【问题讨论】:

  • 恕我直言,导航属性比连接更容易使用,.Where(e => e.Attempt == e.ParentNav.ChildNav.Max(x => x.Attempt))

标签: c# linq entity-framework-core


【解决方案1】:

您继续按尝试分组,这意味着每个用户+部分+尝试成为自己的组(可能大小为 1)

从操作的分组部分移除Attempt;仅按用户和部分分组

使用 SQL 解释可能更清楚。你正在这样做:

    SELECT user, section, attempt, MAX(attempt) --max is useless here 
    FROM ...
    GROUP BY user, section, attempt --always a group size of 1

你需要这样做:

    SELECT user, section, MAX(attempt)
    FROM ...
    GROUP BY user, section

【讨论】:

    【解决方案2】:
    var result = await (from exam in db.exams
                            join section in db.sections on exam.SectionId equals 
                            section.Id
                            select new
                            {
                                UserId = exam.UserId,
                                SectionId = exam.SectionId,
                                Attempt = exam.Attempt
                            })
                            .GroupBy(x => new
                            {
                                x.UserId,
                                x.SectionId
                               
                            })
                            .Select(x => new
                            {
                                UserId = x.Key.UserId,
                                SectionId = x.Key.SectionId,
                                Attempt = x.Max(c => c.Attempt)
                            })
                            .ToListAsync();
    

    试试这个,它会起作用的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-01-06
      • 2011-06-27
      • 2017-10-03
      • 1970-01-01
      • 1970-01-01
      • 2011-10-16
      • 1970-01-01
      • 2017-10-18
      相关资源
      最近更新 更多