Saltar al contenido

Convertir DataTable a lista genérica en C#

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.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *