pasar - parse list to datatable c#
Convertir DataTable a la lista genérica? (1)
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;
}
¿Es lo único que podemos pensar en este momento es que debemos hacer algo donde necesitamos que Garbage Collect Ourselves?
¿Pensamientos?
¿Por qué creemos que puede haber una fuga ?:
Estamos obteniendo 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 recibiendo ANTS Profiler para darnos más detalles.
Eso no será una fuga real, pero podría estar tensionando cosas innecesariamente ...
¿Cuántas filas está trabajando? 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, preconstruiré 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. Dado que DataTable
no está fuertemente tipado, HyperDescriptor
sería un siguiente paso lógico (para el rendimiento) después de la siguiente ...
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;
}