2012-03-06 63 views
0

我有一个表AppointmentStatusHistory采用以下格式:分组只有在LINQ查询返回最近的记录

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 
    } 
); 

使用上述返回AppointmentStatusId的 '1'状态时第一= 1/1/2012年和最后= 2/1/2012

要求

我希望有人也许能够给我修改这符合以下条件的一些建议:

  • 如果最最新的状态是当前的周期内, 包括的记录。
  • 如果不是,省略它来自结果集。
+0

您如何确定日期状态是否在当前期间? – Aducci 2012-03-06 14:59:05

+0

@Aducci在AppointmentStatus表中使用'Date'字段 – Nick 2012-03-06 15:01:21

回答

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 
} 

旁注:

我用导航属性做用户过滤。如果你无法工作,请返回连接。

打电话给集团总是很安全的。团体永远不会空虚。在这种情况下,不需要FirstOrDefault。

我在方法风格的查询重用ash变量名,因为它是在两个不同的地方类型未注明声明通信类型。我将其更改为winner中的理解风格查询以更好地沟通意图,因为它在一个可以通过检查来验证类型的地方声明。

此外,我从不使用> =与日期。它只会导致悲伤。

+0

非常感谢您的明确回答和很好的解释。由于我永远不会知道的原因,TaskAppointments未加入AppointmentStatusHistories。哪里是最有效的地方加入这个? – Nick 2012-03-06 15:25:25

+0

@Nick我已更新查询以通过AppointmentStatusHistories的Appointment属性。它确实有意义,两个子任务表(Appointment)不会被导航属性直接关联。 – 2012-03-06 15:31:50