2013-06-26 81 views
2

我一直在尋找如何加入兩個表(數據和DataValues,一對多)和填充類型的字典。加入使用LINQ兩個表,並填寫他們的字典

數據記錄可能是成千上萬(例如500,000或更多),每個數據可能有10到20個數據值,這使得它成爲一個更重的查詢,所以在這裏的性能非常重要。

這裏是我寫的代碼:

// Passed via the arguments, for example, sensorIDs would contain: 
int[] sensorIDs = { 0, 1, 2, 3, 4, 5, 6, 17, 18 }; 
Dictionary<Data, List<DataValue>> dict = new Dictionary<Data, List<DataValue>>(); 

foreach (Data Data in dt.Datas) 
{ 
    var dValues = from d in dt.Datas 
         join dV in dt.DataValues on d.DataID equals dV.DataID 
         where (SensorIDs.Contains(dV.SensorID)) 
         select dV; 
    dict.Add(Data, dValues.ToList<DataValue>()); 
} 

但這種方法有一個顯著的性能問題,需要很長的時間來執行。 不知道我是否需要使用SQL視圖。有什麼建議麼?

+0

你有多大的數據表?每天(只是數據) – Learner

+0

約1200的記錄,並且每個數據可以具有5至18 DataValue。 「數據」表的當前行數是125361 – Arman

+0

您所查詢的是不正確的,也順便說一下,你應該做的'dt.DataValues'一個選擇和包括檢查'Data.DataID == dV.DataID'以及您'where'聲明 – konkked

回答

3

要查詢的方式太多次。你可以在一個查詢中做到這一點。

var dict = (from d in dt.Datas 
      join dV in dt.DataValues on d.DataID equals dv.DataID 
      where SensorIDs.Contains(dv.SensorID) 
      select new { d, dV }).ToDictionary(o => o.d, o => o.dV.ToList()); 

在你foreach循環,你獲取的所有Data,併爲他們每個人,你正在做同樣的事情。

編輯:現在這不是很清楚,但我想你只想加入SensorIDs數組中的DataValue。在這種情況下:

var dict = (from d in dt.Datas 
      let dV = (from dataValue in dt.DataValues 
         where SensorIDs.Contains(dataValue.SensorID) && 
          dataValue.DataID = d.DataID 
         select dataValue) 
      select new { d, dV }).ToDictionary(o => o.d, o => o.dV.ToList()); 
+0

沒有就如何'Data','DataValue'和'SeonsorID'之間的相互關係在他的模型和/或數據庫,我不能肯定地說什麼明確的想法。但是在實體框架中帶有數組的「Contains」轉換爲「IN(..數組中的值)」語句。因此,除非他使用'Contains'的數組非常大,否則它對性能的影響非常小。 –

+0

嗯,謝謝,但返回類型是類型的字典,而我想要>(關注列表!) – Arman

+1

請參閱已編輯的答案 –

0

你不需要foreach循環。嘗試這樣的事情一般:

var columns = dt.Columns.Cast<DataColumn>(); 
dt.AsEnumerable().Select(dataRow => columns.Select(column => 
        new { Column = column.ColumnName, Value = dataRow[column] }) 
       .ToDictionary(data => data.Column, data => data.Value)); 

另外,還要考慮閱讀本:http://blogs.teamb.com/craigstuntz/2010/01/13/38525/

1

你不需要在這種情況下foreach循環,您可以使用組一起創造字典直接從LINQ即應給你更好的表現。

dict=(from DataValue d in dt.DataValues 
      where sensorIDs.Contains(d.SensorID) 
     group d by d.DataID 
      into datavalues 
     join data in dt.Datas 
      on datavalues.Key equals data.DataId 
     select new { 
     Key = data, 
     Value = datavalues 
     }).ToDictionary(a=>a.Key,a=>a.Value.ToList()); 

,或者你可以使用LINQ表達方法

dict = dt.DataValues.Where(d=>sensorIDs.Contains(d.SensorID)) 
      .GroupBy(a=>a.DataID) 
      .Join(dt.Datas,a=>a.Key,a=>a.DataId, 
        (a,b)=>new{Key=b,Value=a.ToList()}) 
     .ToDictionary(a=>a.Key,a=>a.Value); 
相關問題