2009-02-13 17 views
6
public static IList<T> ConvertTo<T>(DataTable table) 
    { 
     if (table == null) 
     { 
      return null; 
     } 

     List<DataRow> rows = new List<DataRow>(); 

     foreach (DataRow row in table.Rows) 
     { 
      rows.Add(row); 
     } 

     return ConvertTo<T>(rows); 
    } 

    public static T ConvertItem<T>(DataTable table) 
    { 
     T obj = default(T); 
     if (table != null && table.Rows.Count > 0) 
     { 
      obj = CreateItem<T>(table.Rows[0]); 
     } 
     return obj; 
    } 


    public static T CreateItem<T>(DataRow row) 
    { 
     T obj = default(T); 
     if (row != null) 
     { 
      obj = Activator.CreateInstance<T>(); 
      Type entityType = typeof(T); 
      PropertyInfo[] properties = entityType.GetProperties(); 

      for (int i = 0; i < properties.Length; i++) 
      { 
       object[] customAttributes = properties[i].GetCustomAttributes(typeof(ColumnAttributes), false); 
       ColumnAttributes dataField = null; 
       if (null != customAttributes && customAttributes.Length > 0 && null != (dataField = customAttributes[0] as ColumnAttributes)) 
       { 
        if (row.Table.Columns.Contains(dataField.FieldName) && !row[dataField.FieldName].GetType().FullName.Equals("System.DBNull")) 
        { 
         properties[i].SetValue(obj, row[dataField.FieldName], null); 
        } 
       } 
      } 
     } 
     return obj; 
    } 

एकमात्र चीज जो हम अभी सोच सकते हैं वह यह है कि हमें कुछ ऐसा करना होगा जहां हमें कचरा खुद को इकट्ठा करने की ज़रूरत है?जेनेरिक सूची में डेटाटेबल कनवर्ट करें?

विचार?

क्यों हमें लगता है कि एक रिसाव ?:

हम मेमोरी त्रुटियाँ से बाहर हो रही है हो सकता है। यदि किसी पृष्ठ को इस प्रकार के रूपांतरण का उपयोग करने के लिए व्यावसायिक तर्क की आवश्यकता नहीं है, तो II6 प्रक्रिया बढ़ती नहीं है, लेकिन जब हम इसका उपयोग करने वाले किसी पृष्ठ को दबाते हैं, तो यह बढ़ता है।

हमें वर्तमान में अधिक जानकारी देने के लिए एएनटीएस प्रोफाइलर मिल रहा है।

+0

आप एक रिसाव की क्या सबूत है तुम्हारे पास हो सकता है? –

+0

वास्तव में समस्या कहां है? –

+0

आर यू usin 'nHIbernate? – renegadeMind

उत्तर

9

कि एक वास्तविक नहीं होगा रिसाव, लेकिन यह बातें अनावश्यक रूप से जोर दिया जा सकता है ...

तुम पर कितने पंक्तियों काम कर रहे हैं? ध्यान दें कि प्रतिबिंब एक दर्द है, और GetCustomAttributes जैसी चीजों को हर कॉल एक नई सरणी लौटा सकता है (इसलिए आप इसे एक बार करना चाहते हैं, एक बार प्रति-संपत्ति-प्रति-पंक्ति नहीं)।

व्यक्तिगत रूप से, मैं जो काम करना चाहता हूं उसे पूर्व-निर्माण करना चाहता हूं ... नीचे कुछ ऐसा।

ध्यान दें कि अगर मैं यह बहुत कुछ कर रहा था, तो मैं या तो HyperDescriptor पर स्विच करूँगा, या यदि .NET 3.5 एक विकल्प था, तो शायद एक संकलित अभिव्यक्ति हो। DataTable दृढ़ता से टाइप नहीं कर रहा है के बाद से, HyperDescriptor एक तार्किक अगले कदम (प्रदर्शन के लिए) नीचे के बाद ...

sealed class Tuple<T1, T2> 
{ 
    public Tuple() {} 
    public Tuple(T1 value1, T2 value2) {Value1 = value1; Value2 = value2;} 
    public T1 Value1 {get;set;} 
    public T2 Value2 {get;set;} 
} 
public static List<T> Convert<T>(DataTable table) 
    where T : class, new() 
{ 
    List<Tuple<DataColumn, PropertyInfo>> map = 
     new List<Tuple<DataColumn,PropertyInfo>>(); 

    foreach(PropertyInfo pi in typeof(T).GetProperties()) 
    { 
     ColumnAttribute col = (ColumnAttribute) 
      Attribute.GetCustomAttribute(pi, typeof(ColumnAttribute)); 
     if(col == null) continue; 
     if(table.Columns.Contains(col.FieldName)) 
     { 
      map.Add(new Tuple<DataColumn,PropertyInfo>(
       table.Columns[col.FieldName], pi)); 
     } 
    } 

    List<T> list = new List<T>(table.Rows.Count); 
    foreach(DataRow row in table.Rows) 
    { 
     if(row == null) 
     { 
      list.Add(null); 
      continue; 
     } 
     T item = new T(); 
     foreach(Tuple<DataColumn,PropertyInfo> pair in map) { 
      object value = row[pair.Value1]; 
      if(value is DBNull) value = null; 
      pair.Value2.SetValue(item, value, null); 
     } 
     list.Add(item); 
    } 
    return list;   
} 
+0

धन्यवाद इस में देखेंगे :) – TimLeung

+0

मैं मार्क से सहमत हूं। आपका कोड धीमा और काफी जटिल दोनों है! इसके अलावा आपको गुणों के प्रकारों की जांच करनी चाहिए ताकि आप एक int के मान को स्ट्रिंग मान पर सेट करने का प्रयास न करें और इसी तरह। –

संबंधित मुद्दे