2009-02-13 4 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; 
    } 

Это единственное, о чем мы можем думать прямо сейчас, так это то, что мы должны делать что-то, где нам нужно, чтобы Мусор собирал себя?Преобразование DataTable в общий список?

Мысли?

Почему мы думаем, что может быть утечка ?:

Мы получаем из-за ошибок памяти. Если на странице не требуется, чтобы бизнес-логика использовала этот тип преобразования, процесс II6 не растет, но когда мы попадаем на страницу, которая его использует, она растет.

В настоящее время мы ищем ANTS Profiler, чтобы предоставить нам более подробную информацию.

+0

, что свидетельствует о течи у вас есть? –

+0

Где проблема? –

+0

r u 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 для строкового значения и так далее. –

Смежные вопросы