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

Eso es lo único que podemos pensar en este momento es que debemos estar haciendo algo donde tenemos que recoger la basura nosotros mismos?¿Convertir DataTable a lista genérica?

¿Pensamientos?

Por qué pensamos que podría haber una fuga ?:

Estamos recibiendo errores de memoria insuficiente. Si una página no requiere lógica de negocios para usar este tipo de conversión, el proceso II6 no crece, pero cuando alcanzamos una página que lo usa, crece.

Actualmente estamos obteniendo ANTS Profiler para darnos más detalles.

+0

lo que evidencia de una fuga tiene? –

+0

¿Dónde está el problema exactamente? –

+0

r u usin 'nHIbernate? – renegadeMind

Respuesta

9

que no va a ser un real fugas, pero podría ser subrayando cosas innecesariamente ...

¿Cuántas filas que están trabajando sobre? Tenga en cuenta que la reflexión es un problema, y ​​que cada llamada a cosas como GetCustomAttributes puede devolver una nueva matriz (por lo que desea hacer eso una vez, no una vez por propiedad por fila).

Personalmente, pre-construiré el trabajo que pretendo hacer ... algo como a continuación.

Tenga en cuenta que si estuviera haciendo esto mucho, cambiaría a HyperDescriptor, o si .NET 3.5 era una opción, tal vez una expresión compilada. Desde DataTable no es inflexible de tipos, HyperDescriptor sería un paso lógico siguiente (para el rendimiento) después de la continuación ...

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

gracias se verá en esto :) – TimLeung

+0

Estoy de acuerdo con Marc. ¡Tu código es lento y bastante complicado! También debe verificar los tipos de propiedades para que no intente establecer el valor de un int en un valor de cadena, etc. –