Convertir un IEnumerable<T> a DataTable - El blog de Javier Torrecilla

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.

Published 4/4/2012 12:15 por Javier Torrecilla
Archivado en: ,
Comparte este post:
http://geeks.ms/blogs/jtorrecilla/archive/2012/04/04/convertir-un-ienumerable-lt-t-gt-a-datatable.aspx