Tengo una DataTable fuertemente tipada del tipo MyType
, me gustaría convertirla en un List<MyType>
.Convertir DataTable a la lista <T>
¿Cómo puedo hacer esto?
Gracias.
Tengo una DataTable fuertemente tipada del tipo MyType
, me gustaría convertirla en un List<MyType>
.Convertir DataTable a la lista <T>
¿Cómo puedo hacer esto?
Gracias.
Hay métodos de extensión Linq para DataTable.
Agregar referencia a: System.Data.DataSetExtensions.dll
A continuación se incluyen los nombres: using System.Data.DataSetExtensions
Finalmente, puede utilizar las extensiones de Linq en conjunto de datos y tablas de datos:
var matches = myDataSet.Tables.First().Where(dr=>dr.Field<int>("id") == 1);
En .Net 2.0 aún puede agregar genérica método:
public static List<T> ConvertRowsToList<T>(DataTable input, Convert<DataRow, T> conversion) {
List<T> retval = new List<T>()
foreach(DataRow dr in input.Rows)
retval.Add(conversion(dr));
return retval;
}
¿Hay alguna manera fácil si se bloquea con .NET 2.0? – auujay
+1 Sweeeeeet! Pero, ¿qué es la palabra clave 'Convert' aquí? ¿Te refieres a 'Convertidor'? – MoonKnight
@Keith - Tiene que ser Convert ** er **
Asumiendo que su DataRow
s heredan de su propio tipo, dicen MyDataRowType
, esto debería funcionar:
List<MyDataRowType> list = new List<MyDataRowType>();
foreach(DataRow row in dataTable.Rows)
{
list.Add((MyDataRowType)row);
}
Esto es suponiendo, como usted ha dicho en un comentario, que está utilizando .NET 2.0 y no tiene acceso a los métodos de extensión LINQ.
¿por qué no simplemente hacer una lista
@Mike: dado que el OP dice que tiene una DataTable fuertemente tipada, supongo que preferiría mantener esa fuerte tipeación en sus resultados. –
@ Adam, sí, me gustaría mantener el tipeo fuerte. Tengo acceso a Linq ahora en este proyecto –
A continuación se hace de una sola línea:
dataTable.Rows.OfType<DataRow>()
.Select(dr => dr.Field<MyType>(columnName)).ToList();
[Editar : Agregar una referencia a System.Data.DataSetExtensions
a su proyecto si esto no se compila]
¿Cuál es el valor de columnName aquí? – user123456
IEnumerable<DataRow> rows = dataTable.AsEnumerable();
(System.Data .DataSetExtensions.dll)IEnumerable<DataRow> rows = dataTable.Rows.OfType<DataRow>();
(System.Core.dll)Tabla de datos a la lista
#region "getobject filled object with property reconized"
public List<T> ConvertTo<T>(DataTable datatable) where T : new()
{
List<T> Temp = new List<T>();
try
{
List<string> columnsNames = new List<string>();
foreach (DataColumn DataColumn in datatable.Columns)
columnsNames.Add(DataColumn.ColumnName);
Temp = datatable.AsEnumerable().ToList().ConvertAll<T>(row => getObject<T>(row, columnsNames));
return Temp;
}
catch
{
return Temp;
}
}
public T getObject<T>(DataRow row, List<string> columnsName) where T : new()
{
T obj = new T();
try
{
string columnname = "";
string value = "";
PropertyInfo[] Properties;
Properties = typeof(T).GetProperties();
foreach (PropertyInfo objProperty in Properties)
{
columnname = columnsName.Find(name => name.ToLower() == objProperty.Name.ToLower());
if (!string.IsNullOrEmpty(columnname))
{
value = row[columnname].ToString();
if (!string.IsNullOrEmpty(value))
{
if (Nullable.GetUnderlyingType(objProperty.PropertyType) != null)
{
value = row[columnname].ToString().Replace("$", "").Replace(",", "");
objProperty.SetValue(obj, Convert.ChangeType(value, Type.GetType(Nullable.GetUnderlyingType(objProperty.PropertyType).ToString())), null);
}
else
{
value = row[columnname].ToString().Replace("%", "");
objProperty.SetValue(obj, Convert.ChangeType(value, Type.GetType(objProperty.PropertyType.ToString())), null);
}
}
}
}
return obj;
}
catch
{
return obj;
}
}
#endregion
colección IEnumerable Para dataTable
#region "New DataTable"
public DataTable ToDataTable<T>(IEnumerable<T> collection)
{
DataTable newDataTable = new DataTable();
Type impliedType = typeof(T);
PropertyInfo[] _propInfo = impliedType.GetProperties();
foreach (PropertyInfo pi in _propInfo)
newDataTable.Columns.Add(pi.Name, pi.PropertyType);
foreach (T item in collection)
{
DataRow newDataRow = newDataTable.NewRow();
newDataRow.BeginEdit();
foreach (PropertyInfo pi in _propInfo)
newDataRow[pi.Name] = pi.GetValue(item, null);
newDataRow.EndEdit();
newDataTable.Rows.Add(newDataRow);
}
return newDataTable;
}
gracias por todos los mensajes .... lo he hecho con el uso de LINQ consulta, para ver esta visita la siguiente enlace
http://codenicely.blogspot.com/2012/02/converting-your-datatable-into-list.html
Crear una lista con ty pe por extender la tabla de datos con la llamada AsEnumerable.
var mylist = dt.AsEnumerable(). ToList();
¡Salud!Feliz Codificación
Una tabla de datos no tiene un método AsEnumerable a menos que su solución necesite una referencia y el uso para funcionar. – johnstaveley
Prueba este código y ésta es la manera más fácil de convertir tabla de datos a la lista
List<DataRow> listtablename = dataTablename.AsEnumerable().ToList();
Recibo este error; \t 'System.Data.EnumerableRowCollection
descifrado ahora, agregado usando System.Linq; – Salim
List<MyType> listName = dataTableName.AsEnumerable().Select(m => new MyType()
{
ID = m.Field<string>("ID"),
Description = m.Field<string>("Description"),
Balance = m.Field<double>("Balance"),
}).ToList()
Agradable, muy elegante. –
¿Qué es
MyType es un objeto que crearías antes del código mostrado arriba con las mismas variables (ID, Descripción, Balance) –
favor, prueba este código:
public 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();
}
El ConvertToList método que se publica a continuación y usos la reflexión funciona perfectamente para mí. Gracias.
Hice una pequeña modificación para que funcione con las conversiones en los tipos de propiedades T.
public 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))
{
PropertyInfo pI = objT.GetType().GetProperty(pro.Name);
pro.SetValue(objT, row[pro.Name] == DBNull.Value ? null : Convert.ChangeType(row[pro.Name], pI.PropertyType));
}
}
return objT;
}).ToList();
}
Espero que ayude. Saludos.
Gracias, Gilda. Esa función realmente funciona bien y también es rápida. – windchaser
puede convertir su datatable en una lista. comprobar el siguiente enlace
https://stackoverflow.com/a/35171050/1805776
public static class Helper
{
public static List<T> DataTableToList<T>(this DataTable dataTable) where T : new()
{
var dataList = new List<T>();
//Define what attributes to be read from the class
const System.Reflection.BindingFlags flags = System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance;
//Read Attribute Names and Types
var objFieldNames = typeof(T).GetProperties(flags).Cast<System.Reflection.PropertyInfo>().
Select(item => new
{
Name = item.Name,
Type = Nullable.GetUnderlyingType(item.PropertyType) ?? item.PropertyType
}).ToList();
//Read Datatable column names and types
var dtlFieldNames = dataTable.Columns.Cast<DataColumn>().
Select(item => new
{
Name = item.ColumnName,
Type = item.DataType
}).ToList();
foreach (DataRow dataRow in dataTable.AsEnumerable().ToList())
{
var classObj = new T();
foreach (var dtField in dtlFieldNames)
{
System.Reflection.PropertyInfo propertyInfos = classObj.GetType().GetProperty(dtField.Name);
var field = objFieldNames.Find(x => x.Name == dtField.Name);
if (field != null)
{
if (propertyInfos.PropertyType == typeof(DateTime))
{
propertyInfos.SetValue
(classObj, convertToDateTime(dataRow[dtField.Name]), null);
}
else if (propertyInfos.PropertyType == typeof(Nullable<DateTime>))
{
propertyInfos.SetValue
(classObj, convertToDateTime(dataRow[dtField.Name]), null);
}
else if (propertyInfos.PropertyType == typeof(int))
{
propertyInfos.SetValue
(classObj, ConvertToInt(dataRow[dtField.Name]), null);
}
else if (propertyInfos.PropertyType == typeof(long))
{
propertyInfos.SetValue
(classObj, ConvertToLong(dataRow[dtField.Name]), null);
}
else if (propertyInfos.PropertyType == typeof(decimal))
{
propertyInfos.SetValue
(classObj, ConvertToDecimal(dataRow[dtField.Name]), null);
}
else if (propertyInfos.PropertyType == typeof(String))
{
if (dataRow[dtField.Name].GetType() == typeof(DateTime))
{
propertyInfos.SetValue
(classObj, ConvertToDateString(dataRow[dtField.Name]), null);
}
else
{
propertyInfos.SetValue
(classObj, ConvertToString(dataRow[dtField.Name]), null);
}
}
else
{
propertyInfos.SetValue
(classObj, Convert.ChangeType(dataRow[dtField.Name], propertyInfos.PropertyType), null);
}
}
}
dataList.Add(classObj);
}
return dataList;
}
private static string ConvertToDateString(object date)
{
if (date == null)
return string.Empty;
return date == null ? string.Empty : Convert.ToDateTime(date).ConvertDate();
}
private static string ConvertToString(object value)
{
return Convert.ToString(ReturnEmptyIfNull(value));
}
private static int ConvertToInt(object value)
{
return Convert.ToInt32(ReturnZeroIfNull(value));
}
private static long ConvertToLong(object value)
{
return Convert.ToInt64(ReturnZeroIfNull(value));
}
private static decimal ConvertToDecimal(object value)
{
return Convert.ToDecimal(ReturnZeroIfNull(value));
}
private static DateTime convertToDateTime(object date)
{
return Convert.ToDateTime(ReturnDateTimeMinIfNull(date));
}
public static string ConvertDate(this DateTime datetTime, bool excludeHoursAndMinutes = false)
{
if (datetTime != DateTime.MinValue)
{
if (excludeHoursAndMinutes)
return datetTime.ToString("yyyy-MM-dd");
return datetTime.ToString("yyyy-MM-dd HH:mm:ss.fff");
}
return null;
}
public static object ReturnEmptyIfNull(this object value)
{
if (value == DBNull.Value)
return string.Empty;
if (value == null)
return string.Empty;
return value;
}
public static object ReturnZeroIfNull(this object value)
{
if (value == DBNull.Value)
return 0;
if (value == null)
return 0;
return value;
}
public static object ReturnDateTimeMinIfNull(this object value)
{
if (value == DBNull.Value)
return DateTime.MinValue;
if (value == null)
return DateTime.MinValue;
return value;
}
}
Hay un pequeño example que puede utilizar
DataTable dt = GetCustomersDataTable(null);
IEnumerable<SelectListItem> lstCustomer = dt.AsEnumerable().Select(x => new SelectListItem()
{
Value = x.Field<string>("CustomerId"),
Text = x.Field<string>("CustomerDescription")
}).ToList();
return lstCustomer;
Probablemente tenga más escenas para convertir DataTable en Diccionario de la lista. – Vadim
@Vadim: ¿Qué te haría decir eso? –
DataTable tiene filas y columnas. El diccionario representa esta estructura mucho mejor que List. – Vadim