Convertir un IEnumerable<T> a DataTable

Introducción

En este post vamos a ver como llevar a cabo la exportación de un objeto IEnumerable<T> a un DataTable. Pero, espera!!! Ya existe un método extensor CopyToDataTable, que parece realizar esta acción.

Todo parece que sí, pero parece demasiado bonito. Si nos fijamos en la firma del método:

   1: public static DataTable CopyToDataTable<T>(

   2:     this IEnumerable<T> source

   3: )

   4: where T : DataRow

Veremos que este método, solo lo podremos utilizar en el caso de que T sea de tipo DataRow o implemente a DataRow.

Bueno, el porque del post es debido a una preguntaba que lanzó ayer en Twitter @Zpektrum, sobre porque no podía utilizar dicho método con una consulta Linq.

Código:

Para ilustrar el ejemplo vamos a ver una query linq contra un DataTable:

   1: var query = from t in dt1.AsEnumerable()

   2:                         select new

   3:                         {

   4:                             ID = t.Field<string>("ID"),

   5:                             Nombre = t.Field<string>("Name")

   6:                         };

Como podeís apreciar estamos realizando una consulta sobre las filas de la tabla dt1, y escogiendo las columnas ID y Nombre. El resultado de esta consulta va a devolver un IEnumerable<T> donde T va a ser un tipo anónimo, por lo que dicho tipo no va a ser DataRow y no vamos a tener disponible el método CopyToDataTable.

Bien, para construir nuestro nuevo método extensor, tendremos que definir una nueva clase estática y un método estático que retorne un objeto de Tipo DataTable, y haremos que el método sea genérico.

   1: public static class IEnumerableExtensions

   2:     {

   3:         public static DataTable CopyAnonymusToDataTable<T>(this IEnumerable<T> info)

   4:         {

   5:             var type = typeof(T);

   6:             if (type.Equals(typeof(DataRow))) 

   7:                 return (info as IEnumerable<DataRow>).CopyToDataTable();

   8:             DataTable dt = new DataTable();

   9:             DataRow r;

  10:             type.GetProperties().ToList().ForEach(a=>  dt.Columns.Add(a.Name));

  11:             foreach (var c in info)

  12:             {

  13:                 r = dt.NewRow();

  14:                 c.GetType().GetProperties().ToList().ForEach(a => r[a.Name] = a.GetValue(c,null));

  15:                 dt.Rows.Add(r);

  16:             }

  17:             return dt;

  18:         }

  19:         

  20:     }

Para que el método sea un método extensor es necesario que sea estático, que este contenido en una clase estática y que su primer parámetro tenga el modificador “this” y el tipo que va a extender.

Explicando el método:

El método es sencillo, en primer lugar comprobamos que si el tipo de T es DataRow que ejecute el método CopyToDataTable ya existente.

En caso contrario, a través de reflectión obtendremos las propiedades del Tipo T, e iremos definiendo nuevas columnas con el nombre de dichas propiedades en la tabla resultante.

Por último, iteraremos sobre el contenido de la colección e iremos agregando las filas para devolverlos.

Ejecución del método:

Continuando con el ejemplo anterior:

   1: var query = (from t in dt1.AsEnumerable()

   2:                         select new

   3:                         {

   4:                             ID = t.Field<string>("ID"),

   5:                             Nombre = t.Field<string>("Name")

   6:                         }).CopyAnonymusToDataTable();

De está manera query, será de tipo DataTable y ya podremos manejar dicha tabla a nuestro gusto.

 

Un saludo y espero que os sea de utilidad.

Deja un comentario

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