2012-10-19 47 views
0

我不是一個LINQ程序員,所以這有點讓我感到困惑。我有兩個表格:第一個帶有StartDate和EndDate的Schedule,加上ID;其次,具有InstanceDate和ScheduleID的ScheduleInstance表。對於Schedule.StartDate和Schedule.EndDate之間的每一天,我都需要創建一個ScheduleInstance行 - 但是,只需要提前24小時。由於在24小時內預先創建並刪除了日程表,我必須每n分鐘產生一個檢查器,以檢查ScheduleID的ScheduleInstance是否存在於該24小時窗口內。Linq左不在右表

型號:

public class Schedule 
{ 
    public int ID { get; set; } 
    public DateTime StartDate { get; set; } 
    public DateTime EndDate { get; set; } 
} 
public class ScheduleInstance 
{ 
    public int ID { get; set; } 
    public int ScheduleID { get; set; } 
    public DateTime InstanceDate { get; set; } 
} 

的LINQ的開始:

var skeds = from sked in context.Schedules 
      join instance in context.ScheduleInstances 
       on sked.ID equals instance.ScheduleID 
      where ((sked.StartDate <= DateTime.Now) && (sked.EndDate >= DateTime.Now)) 
      select sked.ID; 

(顯然是錯誤的)

總之,我需要得到Schedule.ID的列表,其中一個ScheduleInstance對於ScheduleInstance.InstanceDate在接下來的24小時內不存在。

非常感謝您的幫助。

UPDATE

 DateTime tomorrow = DateTime.Now.AddDays(1); 
     var skeds = from sked in context.Schedules 
        join instance in context.ScheduleInstances 
         on sked.ID equals instance.ScheduleID into g 
        where (sked.StartDate <= tomorrow) && 
          (sked.EndDate >= tomorrow) && 
          !g.Any() 
        select sked; 

這現在工作在一個實例被創建(在後面的代碼,這裏不相關),如果不爲明天存在。如果我將StartDate設置爲「現在+2分鐘」,那麼在2分鐘後,該計劃將被創建 - 完美。但是,如果我24小時提前,我應該會得到一大堆新實例。重申一下,如果現在計劃的開始日期是30天,並且結束日期是30天,那麼最終應該有31個實例,並且每個新實例都要提前24小時創建。

回答

0

一方面,我應該採用吻原則。另一方面,我有三個查詢,而不是一個。但它的作品!

 var instances = from inst in context.ScheduleInstances 
         where (inst.StartDateTime >= DateTime.Now) 
         && (inst.StartDateTime < tomorrow) 
         select inst; 

     var skeds = from sked in context.Schedules 
        where (sked.StartDate <= DateTime.Now) 
        && (sked.EndDate >= tomorrow) 
        select sked; 

     var none = from sked in skeds 
        join inst in instances 
        on sked.ID equals inst.ScheduleID 
        into tg 
        from tcheck in tg.DefaultIfEmpty() 
        where tcheck == null 
        select sked; 
1

我相信這將這樣的伎倆

var today = DateTime.Now; 
var nextDay = today.AddDays(1); 
var scheds = from sched in context.Schedules       
      join instance in context.ScheduleInstances 
       on sched.ID equals instance.ScheduleID into schedInstances 
      where (sched.StartDate >= today) && 
        (sched.EndDate <= nextDay) && 
        !schedInstances.Any() 
      select sched.ID; 
+0

這似乎是在正確的線 - 謝謝。它不喜歡Now.AddDays,所以我把它從查詢中拉出來,並有一個等價的局部變量。另外,StartDate和EndDate <=/=>是錯誤的。但是,似乎只創建了一個實例,因爲沒有過濾器。我會在我原來的問題中發佈更新後的代碼。 – GeoffM

+0

@GeoffM當然,將下一天變量移動到當地人是一個很好的決定。但> =和<=應該工作。根據我的理解,您需要在24小時內檢查時間表 –

+0

感謝您的更新。例如,> =/<=將不起作用,因爲StartDate可能在一個月前,EndDate在六個月內。這個想法是爲開始和結束之間的每一天創建一個新的實例記錄,但只提前一天。因此,在這個例子中,截至今天,自StartDate以來,我應該擁有大約30條記錄,並且在六個月的時間內,大致應該有另外6條記錄。 – GeoffM

0

試試這個:(未經測試)

var skeds = from sked in context.Schedules 
      from instance in context.ScheduleInstances 
      where (sked.ID == instance.ScheduleID) && ((sked.StartDate <= DateTime.Now) && sked.EndDate >= DateTime.Now)) 
      select sked.ID; 
+0

我認爲這隻會返回* do *存在的實例的計劃ID,而不會返回*不*的實例ID。 – GeoffM

1

所以,你要的是有計劃的開始日期和明天之間的每天不到一個實例時間表?這裏有一個大概的想法:

DateTime tomorrow = DateTime.Now.AddDays(1); 
var skeds = from sked in context.Schedules 
      join instance in context.ScheduleInstances 
       on sked.ID equals instance.ScheduleID into g 
      let instances = g.Where(x => x.InstanceDate >= sked.StartDate && 
             x.InstanceDate <= tomorrow) 
      where (sked.StartDate <= tomorrow) && 
        (sked.EndDate >= tomorrow) && 
        (instances.Count() < (tomorrow - sked.StartDate).Days) 
      select sked; 
+0

「DbArithmeticExpression參數必須具有數字通用類型。」我無法確定它出現問題的地方! – GeoffM

+0

問題似乎是(明天 - sked.StartDate)。天節。我試圖想出一個解決方案。順便說一句,如果我用1替換它,那麼明天的實例就會被創建,但不會在第二天(提前24小時系統時鐘)。 – GeoffM

+0

謝謝 - 這是有幫助的。 – GeoffM