2012-03-06 60 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