对LINQ查询中的最新记录进行分组并仅返回

本文关键字:返回 新记录 查询 LINQ 最新 | 更新日期: 2023-09-27 18:27:00

我有一个以下格式的表AppointmentStatusHistory

AppointmentId   AppointmentStatusId   Date
========================================================
1               1                     2/1/2012 (2nd January)
1               2                     2/2/2012 (2nd February)

我目前对此运行了一个查询,以返回指定时间段内约会的"最近"状态

我的LINQ查询

items = (from t1 in db.AppointmentStatusHistories
         from t2 in db.TaskAppointments
                      .Where(o => (o.ID == t1.AppointmentId))
         from t3 in db.Tasks
                      .Where(o => (o.Task_ID == t2.Parent_Task_ID))
         where t1.Timestamp >= first && t1.Timestamp <= last
            && t3.Creator == user
         group t1 by t1.AppointmentId into grp
         select new UserAppointmentTargetModel
         {
             AppointmentId = grp.Key,
             AppointmentStatusId = grp.OrderByDescending(g => g.Timestamp)
                                      .FirstOrDefault()
                                      .AppointmentStatusId
    }
);

当第一个=2012年1月1日,最后一个=2012月2日时,使用以上返回约会状态Id状态为"1"。

要求

我希望有人能给我一些建议,修改它以满足以下条件:

  • 如果最新状态在当前期间内,则包括记录
  • 如果不是,则从结果集中省略

对LINQ查询中的最新记录进行分组并仅返回

您只需要将过滤的last部分移动到分组/winnerpicking之后。

db.AppointmentStatusHistories
.Where(ash => first <= ash.TimeStamp) //omit all records that are before the range
.Where(ash => ash.Appointment.TaskAppointments.Any(ta => ta.Task.Creator == user))
.GroupBy(ash => ash.AppointmentId)
.Select(g => g.OrderByDescending(ash => ash.TimeStamp).First()) //pick a winner
.Where(ash => ash.TimeStamp <= last) //omit winners that are after the range
.Select(ash => new UserAppointmentTargetModel()
{
  AppointmentId = ash.AppointmentId,
  AppoinementStatusId = ash.AppointmentStatus,
  Date = ash.Timestamp
}

(上述强制性查询理解语法形式)

from ash in db.AppointmentStatusHistories
where first <= ash.TimeStamp
where ash.Appointment.TaskAppointments.Any(ta => ta.Task.Creator == user)
group ash by ash.AppointmentId into g
let winner = g.OrderByDescending(ash => ash.TimeStamp).First()
where winner.TimeStamp <= last
select new UserAppointmentTargetModel()
{
  AppointmentId = winner.AppointmentId,
  AppoinementStatusId = winner.AppointmentStatus,
  Date = winner.Timestamp
}

旁注:

我使用导航属性来进行用户筛选。如果你不能做到这一点,那就回到联接。

在小组中呼叫First总是安全的。群组从来都不是空的。在这种情况下,不需要FirstOrDefault。

我在方法样式查询中重用了ash变量名来传递类型,因为它是在两个不同的地方声明的,而这两个地方没有声明类型。我在理解风格查询中将其更改为winner,以更好地传达意图,因为它是在一个可以通过检查验证类型的地方声明的。

此外,我从不在日期中使用>=。这只能导致悲伤。