2011-05-19 78 views
1

我寫了一個通用數據庫幫助方法,它返回特定實體的記錄。關於優化C#代碼的建議

這裏是我如何做到這一點:

  • 我已經有10個物業也有一個名爲TableName屬性的一類叫做客戶。

  • 有一種方法,只取得Type參數,並返回一個傳入類型的數組。

  • 該方法是如何工作的,通過使用反射得到一個表名,並且激發一個select語句,並且在DataReader的基礎上,它循環遍歷每個colum和傳遞類型的Properties。

因此,問題是假設有100萬條記錄和10個屬性。它循環10(屬性)*(1,000,000條記錄)= 10,000,000次

是否有任何優化的方式來做到這一點,就像使用LINQ對Datareader?

下面是一個代碼

object[] LoadAll(Type type) 
    { 

     try 
     { 
      object obj = Activator.CreateInstance(type); 
      SqlConnection conn = new SqlConnection("connection string"); 
      string tableName = type.GetField("TableName").GetValue(obj) as string; 
      SqlCommand cmd = conn.CreateCommand(); 
      cmd.CommandText = string.Format("select * from {0}", tableName); 
      conn.Open(); 
      List<object> list = new List<object>(); 
      SqlDataReader reader = cmd.ExecuteReader(); 

      while (reader.Read()) 
      { 
       object obj1 = Activator.CreateInstance(type); 
       foreach (PropertyInfo propertyInfo in type.GetProperties()) 
       { 
        obj.GetType().GetProperty(propertyInfo.Name).SetValue(obj1,reader[propertyInfo.Name],null); 
       } 

       list.Add(obj1); 
      } 


     } 

感謝名單

+0

@BreakHead只是好奇,爲什麼你想在你的應用程序中使用這樣的類填充10Lacs記錄?在這裏介紹一些分頁機制是不是更好? – 2011-05-19 11:26:09

+3

這個計算對我來說沒有意義:'10(屬性)*(10條記錄)= 10000000'?從什麼時候開始10次10​​次,然後100次? – 2011-05-19 11:27:24

+1

@Tony 1 [十萬](http://en.wikipedia.org/wiki/Lakh)= 100,000。 – Rup 2011-05-19 11:34:37

回答

0

聽起來像是你的計算實體的每個實例的大小。你應該有一些元數據控制器,它爲每個表名緩存一個實體的大小。假設我理解你的問題是正確的,對於同一個表名,大小將始終相同。

0

如果我正確地解決了這個問題,聽起來好像你可以簡單地讓DB爲你完成工作。你說「並且發出一個選擇性陳述」:你能否發出一個更明智的選擇陳述來做你正在解釋的事情?

我不完全明白當你說你正在循環每一列時你正在嘗試做什麼。但看看「集團」和「聚集」又名「聚合運營商」,看看有沒有人可以幫助你。

1

嘗試像NHibernate一樣的對象關係映射器。

0

從優化的角度來看,不需要爲1百萬條記錄維護一個到db的連接,意味着你正在與數據庫進行交互,直到循環結束。 :(。 優化,你緩存整個表記錄在一些數據集中,然後迭代它。不要長時間的連接到數據庫的生活。希望它會回答你的問題。:)

0

你可能可能稍微收緊環路以減少涉及反射的呼叫。你並不需要創建初始obj之一:

PropertyInfo[] properties = type.GetProperties(); 
while (reader.Read()) 
{ 
    object obj = Activator.CreateInstance(type); 
    foreach (PropertyInfo propertyInfo in properties) 
    { 
     propertyInfo.SetValue(obj, reader[propertyInfo.Name], null); 
    } 
    list.Add(obj); 
} 

但要得到它更快,你可以給通過LoadAll()功能的方式向行映射到一個新的對象,沿着線的東西:

IEnumerable<T> LoadAll<T>(Func<DataReader, T> map) { 
    var tablename = typeof(T).GetField("TableName)...... 
    // other connection and query stuff 
    while (reader.Read()) { 
     yield return map(reader); 
    } 
} 
// use it like: 
var kittens = LoadAll<Kitten>(reader => new Kitten { 
    Name = (string)reader["Name"], 
    Colour = (string)reader["Colour"] 
}); 

此,還可以對從數據層到您的域對象,例如使用反射你的方法將需要大量的修改來處理enum屬性,這將很簡單代碼中的所述映射多個控制顯式映射函數。

-1

您可以嘗試安裝免費試用版ReSharper,其檢測工具可以提供多種方法來優化您的代碼。