2017-02-08 25 views
0

我的模型有:連接到如何將包含多個Linq請求的因子分解?

  • 幾個DeviceStatus一個強制性Device
  • 幾個Device連接到一個強制性Panel

當我查詢DeviceStatus,我需要有連接到它DevicePanel在查詢結果中。

... DeviceStatus.Device在查詢結果中爲空。

這裏的LINQ查詢:

using (var actiContext = new ActigraphyContext()) 
{ 
    var todayStatus = 
     from s in actiContext.DeviceStatus.Include(s1 => s1.Device.Panel) 
     where DbFunctions.TruncateTime(s.TimeStamp) == DbFunctions.TruncateTime(DateTimeOffset.Now) 
       && s.Device.Panel.Mac == mac 
       && (s.Device.Ty == 4 || s.Device.Ty == 9) 
     select s; 

    // var tempList = todayStatus.toList(); 

    var todayLastStatus = 
     from s in todayStatus.Include(s1 => s1.Device.Panel) 
     let lastTimeStamp = todayStatus.Max(s1 => s1.TimeStamp) 
     where s.TimeStamp == lastTimeStamp 
     select s; 

    var requestResult = todayLastStatus.FirstOrDefault(); 

    return requestResult; 
} 

如果我取消對該行// var tempList = todayStatus.toList();,在不使用tempList,它的工作原理:requestResult.Device設置! 但是,不好的一面是todayStatus.toList觸發一個帶來大量數據的請求。

那麼如何獲取DeviceStatus及其相關對象呢?

注:數據庫的背後,是SQL Server 2012中

回答

2

當你調用一個包括()在LINQ查詢,它執行熱切加載。

如MSDN記載: 預先加載是過程,由此對一種類型的實體的查詢還加載相關的實體作爲查詢的一部分。通過使用Include方法可以實現預加載。 當實體被讀取時,相關數據隨之一起被檢索。這通常會導致一個單一的連接查詢來檢索所需的所有數據。使用Include方法指定加載加載。

所以你需要調用.toList()來完成查詢的執行。

由於數據非常龐大,您可以使用Select子句按照您的要求提取相關的特定列。

var todayStatus = 
    from s in actiContext.DeviceStatus 
    .Include(s1 => s1.Device.Panel.Select(d => new 
              { 
               d.DeviceId, 
               d.DeviceName, 
               d.PanelID 
              })) 
    where DbFunctions.TruncateTime(s.TimeStamp) == DbFunctions.TruncateTime(DateTimeOffset.Now) 
      && s.Device.Panel.Mac == mac 
      && (s.Device.Ty == 4 || s.Device.Ty == 9) 
    select s; 

var tempList = todayStatus.toList(); 
+0

我需要只返回一個元素與todayLastStatus.FirstOrDefault(),有太多todayStatus來執行todayStatus.toList(),我需要obejcts的所有屬性。 – abreneliere

+0

不是問題。調用.toList(),而不是調用todayStatus上的.FirstOrDefault()。我已經更新了Select查詢。您可以檢索有限數量的列以滿足您的需求。 – RRM

+0

我不需要第一個,我需要帶lastTimeStamp的那個,爲什麼我執行let lastTimeStamp = todayStatusForMax.Max(s1 => s1。TimeStamp) – abreneliere

-1

查詢實際上並沒有運行,直到您執行ToList()這樣的調用,這就是爲什麼取消註釋該行的作用。如果查詢帶回的數據過多,則需要更改查詢以縮小要回收的數據量。

+1

我已經知道這一點:如何讓設備和麪板連接到狀態而不運行todayStatus請求? – abreneliere

+0

對不起,我誤解了你的問題。 – Freakshow

0

確定這要求是一個更簡單的方法來實現這一目標:

 using (var actiContext = new ActigraphyContext()) 
     { 
      var todayLastStatus = 
       from s in actiContext.DeviceStatus.Include(s1 => s1.Device.Panel) 
       where DbFunctions.TruncateTime(s.TimeStamp) == DbFunctions.TruncateTime(DateTimeOffset.Now) 
         && s.Device.Panel.Mac == mac 
         && (s.Device.Ty == 4 || s.Device.Ty == 9) 
       orderby s.TimeStamp descending 
       select s; 

      var requestResult = todayLastStatus.Take(1).FirstOrDefault(); 

      return requestResult; 
     } 

但問題仍然存在:爲什麼我沒有拿到相關物體在我的第一個要求嗎?

相關問題