c# - array - table parameter stored procedure
Cómo convertir DataTable a List<T> usando Reflections (1)
Tengo una lista genérica de una clase que automáticamente la convierto a DataTable utilizando los métodos de Reflection
y extensión. Ahora quiero hacerlo en dirección inversa. Quiero convertir DataTable
en List.Better para decir que quiero ayuda para escribir un método que esperar una DataTable
y un Type
y buscar automáticamente la propiedad de ese tipo (clase) según el nombre de la columna y asignarle valor al objeto de ese Tipo (clase). Like este código psodu:
private List<T> ConvertToList<T>(DataTable dt)
{
List<string> AllColumns = // Get All Column Names of a DataTable
for(int i=0;i<dt.Rows.Count;i++)
{
foreach(var item in AllColumns )
{
//Get Property According To **ITEM**
//Get Data Of Rows[i][item] and assign it to T.property
}
}
}
¿Como puedo hacer esto?
Editar 1)
Utilizo la respuesta de @Cuong Le así:
var properties = typeof(CustomType).GetProperties().ToList();
List<CustomType> list = ConvertToList<CustomType>(dt, properties);
y:
private List<T> ConvertToList<T>(DataTable dt,List<PropertyInfo> fields) where T : class
{
return dt.AsEnumerable().Select(Convert<T>(fields)).ToList(); <------
}
private T Convert<T>(DataRow row,List<PropertyInfo> fields) where T : class
{
var properties = typeof(T).GetProperties().ToList();
var objT = Activator.CreateInstance<T>();
foreach (var pro in properties)
{
pro.SetValue(objT, row[pro.Name],null);
}
return objT;
}
pero en línea coloco una flecha delante de él obtuve estos dos errores:
Sin sobrecarga para el método ''Convertir'' toma 1 argumentos
y
Los argumentos de tipo para el método ''System.Data.EnumerableRowCollectionExtensions.Select (System.Data.EnumerableRowCollection, System.Func)'' no se pueden deducir del uso. Intente especificar los argumentos de tipo explícitamente.
¿Cómo puedo resolver este problema?
Use el método AsEnumerable()
para admitir LINQ:
private List<T> ConvertToList<T>(DataTable dt)
{
var columnNames = dt.Columns.Cast<DataColumn>()
.Select(c => c.ColumnName)
.ToList();
var properties = typeof(T).GetProperties();
return dt.AsEnumerable().Select(row =>
{
var objT = Activator.CreateInstance<T>();
foreach (var pro in properties)
{
if (columnNames.Contains(pro.Name))
pro.SetValue(objT, row[pro.Name]);
}
return objT;
}).ToList();
}
GetProperties
busca las propiedades del tipo actual, utilizando las restricciones de enlace especificadas.
El enlace aquí: http://msdn.microsoft.com/en-us/library/kyaxdd3x.aspx