2015-02-05 107 views
0

我只是想知道是否有更快或更有效的方法來將DataTable轉換爲對象?什麼是從DataTable填充簡單對象的最快方法?

我目前使用的方法是這樣的:

public class Job { 
    int JobID { get; set; } 
    decimal JobCost { get; set; } 

    Job(DataRow dr) 
    { 
     ID = Convert.ToInt32(dr["ID"]); 
     if(dr["JobCost "] != DBNull.Value) 
      JobCost = Convert.ToDecimal(dr["DelAmt"]); 
    } 
} 

public static List<Job> FillObjects() 
{ 
    DataTable dtJobs = JobController.GetJobTable(); 

    foreach (DataRow dr in dtJobs.Rows) 
    { 
     jobs.Add(new Job(dr));   
    } 

    return jobs 
} 

這是一個明顯簡化的示例,但是這得到與數據表中的許多行和在對象許多屬性相當緩慢。有沒有更快或更有效的方法來做這樣的事情?

在此先感謝您的回覆!

+1

想必在數據表中的項目實際上整數和小數。你應該*鑄造*他們,而不是調用'轉換'。演員陣容*操作簡單。除此之外,除了遍歷每一行,抽出每一個值並將其分配給對象的一個​​字段外,沒有其他選擇。 – Servy 2015-02-05 17:58:11

+0

這些項目*主要是*整數和小數,但是在代碼中數據庫類型和變量類型之間總是沒有確切的關係。 (Disclamer:這不是我的代碼,我已經繼承了系統)。有些數據庫字段是需要轉換爲整數或日期時間的字符串等。 – user3241130 2015-02-05 18:17:18

+0

然後,您應該真正解決該問題;將數字作爲字符串存儲在數據庫中將導致任意數量的不同類型的問題,其中之一是當然所有數據庫查詢都需要花費時間來解析所有查詢結果。 – Servy 2015-02-05 18:20:36

回答

0

不使用實體框架的選擇是有限的東西,就像你已經開發或使用LINQ to放在他們的對象,例如:

dtJobs.AsEnumerable().Select(x=> new Job{ 
            ID = x.Field<int>("ID"), 
            JobCost = x.Field<Decimal>("DelAmt") 
}); 

這將返回作業對象的枚舉,你然後可以用來做任何事情。您目前設置的一個警告是,這不允許返回空值。如果你想這樣做,使用一個可爲空的十進制字段,並在其他地方處理空值。

+0

對於這種類型的操作,使用LINQ不會更慢嗎?我知道可空類型,但這是在一個已經存在的系統中。可空類型與許多現有函數調用不兼容,因爲您無法傳遞int類型?作爲一個整數。將會有很多重寫來完成。 – user3241130 2015-02-05 18:19:03

+0

@ user3241130它不會以某種方式產生重大差異。 – Servy 2015-02-05 18:19:40

+0

夠公平的。感謝您的回答。 – user3241130 2015-02-05 18:28:05

-1

如果順序不重要 - 您可以在數據行上對每個循環使用一個並行來執行此操作。這將會更快地處理。儘管如此,在服務器應用程序中必須小心。

注意:添加到列表中時,我更新爲鎖定列表。您還可以使用併發集合中的集合,而不是使用鎖定。

class Program 
{ 
    static void Main(string[] args) 
    { 
     var sync = new Object(); 
     var dt = new DataTable(); // fill data 
     var jobs = new List<Job>(); 
     Parallel.ForEach(dt.AsEnumerable(), row => 
     { 
      var job = JobFactory.GetJob(row); 
      lock (sync) 
      { 
       jobs.Add(job); 
      } 
     }); 
    } 
} 

public class JobFactory 
{ 
    public static Job GetJob(DataRow d) 
    { 
     var j = new Job(); 

     // do processing here from data row to fill job object 
     return j; 
    } 
} 

public class Job 
{ 

} 
+0

'List'不能同時從多個線程訪問。 – Servy 2015-02-05 18:21:29

+0

如果你只是要同步大部分工作,並行化沒有意義。最終結果幾乎肯定會比串行解決方案慢*。 – Servy 2015-02-06 15:09:09

+0

這實際上取決於從數據行加載每個對象需要多長時間,而線程必須等待將結果轉儲到樹中需要多長時間。證明任何一種理論的唯一方法是針對您正在嘗試解決的問題進行測試。我發現在一些情況下速度較慢,但​​其他情況下速度較快。因人而異!!!! – tsells 2015-02-06 18:44:08

相關問題