我有一个表格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
}
);
使用上述内容在first = 1/1/2012和last = 2/1/2012时返回 AppointmentStatusId 状态为“1”。
要求
我希望有人可以就修改此问题给我一些建议以满足以下条件:
答案 0 :(得分:3)
您只需将过滤的last
部分移至分组/获胜者之后。
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
以更好地传达意图,因为它在一个可以通过检查验证类型的地方声明。
另外,我从不使用&gt; =日期。它只能导致悲伤。