Luego de buscar en varios repositorios y páginas de internet al concluir encontramos la solución que te mostraremos pronto.
Solución:
De hecho, podría acortarlo considerablemente. Puedes pensar en el Select()
método de extensión como un convertidor de tipos. La conversión podría escribirse así:
List target = dt.AsEnumerable()
.Select(row => new Cards
// assuming column 0's type is Nullable
CardID = row.Field(0).GetValueOrDefault(),
CardName = String.IsNullOrEmpty(row.Field(1))
? "not found"
: row.Field(1),
).ToList();
Creo que todas las soluciones se pueden mejorar y hacer que el método sea más general si usa algunas convenciones y reflexión. Digamos que nombra sus columnas en la tabla de datos con el mismo nombre que las propiedades en su objeto, luego podría escribir algo que observe todas las propiedades de su objeto y luego busque esa columna en la tabla de datos para mapear el valor.
Hice lo contrario, es decir… de IList a datatable, y el código que escribí se puede ver en: http://blog.tomasjansson.com/convert-datatable-to-generic-list-extension/
No debería ser tan difícil ir al otro lado, y debería ser tan difícil sobrecargar las funciones para que pueda proporcionar información sobre qué propiedades desea incluir o excluir.
EDITAR:
Así que el código para que funcione es:
public static class DataTableExtensions
private static Dictionary> typeDictionary = new Dictionary>();
public static IList GetPropertiesForType()
var type = typeof(T);
if(!typeDictionary.ContainsKey(typeof(T)))
typeDictionary.Add(type, type.GetProperties().ToList());
return typeDictionary[type];
public static IList ToList(this DataTable table) where T : new()
IList properties = GetPropertiesForType();
IList result = new List();
foreach (var row in table.Rows)
var item = CreateItemFromRow((DataRow)row, properties);
result.Add(item);
return result;
private static T CreateItemFromRow(DataRow row, IList properties) where T : new()
T item = new T();
foreach (var property in properties)
property.SetValue(item, row[property.Name], null);
return item;
Si tiene un DataTable, simplemente puede escribir yourTable.ToList
y creará la lista para usted. Si tiene un tipo más complejo con objetos anidados, debe actualizar el código. Una sugerencia es simplemente sobrecargar el ToList
método para aceptar un params string[] excludeProperties
que contiene todas sus propiedades que no deben ser mapeadas. Por supuesto que puedes agregar algunos null comprobando en el foreach
bucle de la CreateItemForRow
método.
ACTUALIZAR: Agregado static diccionario para almacenar el resultado de la operación de reflexión para hacerlo un poco más rápido. No he compilado el código, pero debería funcionar :).
Sólo una pequeña simplificación. No uso ItemArray:
List list = tbl.AsEnumerable().Select(x => new Person
Id = (Int32) (x["Id"]),
Name = (string) (x["Name"] ?? ""),
LastName = (string) (x["LastName"] ?? "")
).ToList();
Puntuaciones y comentarios
Eres capaz de añadir valor a nuestro contenido colaborando tu experiencia en las aclaraciones.