[How To] Transponer un Objeto DataTable con LINQ
Introducción
Una pregunta bastante utilizada en foros MSDN es como Transponer un DataTable al igual que se puede hacer en Excel.
¿Qué es Transponer una Tabla?
A simple vista será cambiar Columnas por filas.
Podríamos obtener los datos modificados desde la base de datos, con algún quebradero de cabeza. Pero, me he animado a crear un método para ayudar en esta tarea.
Métodos Usados
Bueno, como ya he comentado alguna vez LINQ es algo que me encanta, así que me he decantado a crear un “método extensor” y dos métodos auxiliares en C# y usando LINQ.
En primer lugar, vamos a determinar cuales serán las columnas de la nueva tabla. Para ello, como indicaba antes, las filas originales van a pasar a ser columnas, por lo tanto tantas filas originales, tantas columnas nuevas vamos a tener. Además de ello, agregaremos una nueva columna que será la cabecera de nuestra columna antigua.
1: private static void CreatingColumns(DataTable dtOld, DataTable dtNew)
2: {
3: DataColumn[] arr = new DataColumn[] { new DataColumn("Head") }
4: .ToList()
5: .Union<DataColumn>(dtOld.Rows.Cast<DataRow>()
6: .ToList()
7: .Select(row => new DataColumn(Convert.ToString(row[0])))
8: ).ToArray();
9:
10: dtNew.Columns.AddRange(arr);
11:
12: }
Una vez que hemos definido nuestras columnas, vamos a agregar las nuevas filas:
1: private static void CreatingRows(DataTable dtOld, DataTable dtNew)
2: {
3: dtOld.Columns.Cast<DataColumn>()
4: .ToList()
5: .ForEach(a =>
6: dtNew.Rows.Add(new string[] { a.ColumnName }.Union(
7: dtOld.Rows.Cast<DataRow>()
8: .ToList()
9: .Select(row => row[a.ColumnName])).ToArray()));
10:
11:
12: }
Y por ultimo vamos a crear el método extensor:
1: public static DataTable Transpond(this DataTable dtOld)
2: {
3: DataTable dtNew = new DataTable(dtOld.TableName);
4:
5: Extensions.CreatingColumns(dtOld, dtNew);
6:
7: Extensions.CreatingRows(dtOld, dtNew);
8:
9: return dtNew;
10: }
Bueno, espero que os guste y os sea de utilidad.
He publicado el código fuente aquí.
Saludos!