jueves, 25 de septiembre de 2008

Convertir Listas genericas a DataTables y viceversa

Actualmente tengo un servicio de WCF que por definición del arquitecto realiza una consulta a base de datos y devuelve una lista de un tipo (List) , pero yo lo que en realidad necesito para trabajar es un DataTable. Me puse a investigar un poco sobre como podria hacer esto de la manera mas floja y me tope con el blog de TeraBIThia, alli hay un articulo sobre ello.



Para realizarlo se hace uso de tipos genéricos, se creo una clase generica a la cual se le pasa el tipo de objeto que contiene la lista, en dicha clase estableceremos operaciones genericas que aplican a cualquier tipo que le asignemos a la clase.



Aqui tenemos el código






/// <summary>
/// Clase genérica para convertir una Lista Genérica de elementos en
/// un objeto DataTable
/// </summary>
/// <typeparam name="T">Tipo de datos de los elementos de la Lista.
/// Debe ser una clase con un constructor sin parámetros. ver referencia de clases genericas</typeparam>

public static class Convertidor<T> where T : new()

{

/// <summary>
///
/// </summary>
/// <param name="items"></param>
/// <returns></returns>

public static DataTable ListaToDatatable(List<T> items)

{

// Instancia del objeto a devolver

DataTable dataTable = new DataTable();

// Información del tipo de datos de los elementos del List

Type itemsType = typeof(T);

// Recorremos las propiedades para crear las columnas del datatable

foreach (PropertyInfo prop in itemsType.GetProperties())

{

// Crearmos y agregamos una columna por cada propiedad de la entidad

DataColumn column = new DataColumn(prop.Name);

column.DataType = prop.PropertyType;

dataTable.Columns.Add(column);

}



int j;

// ahora recorremos la colección para guardar los datos
// en el DataTable

foreach (T item in items)

{

j = 0;

object[] newRow = new object[dataTable.Columns.Count];

// Volvemos a recorrer las propiedades de cada item para
// obtener su valor guardarlo en la fila de la tabla

foreach (PropertyInfo prop in itemsType.GetProperties())

{

newRow[j] = prop.GetValue(item, null);

j++;

}

dataTable.Rows.Add(newRow);

}

// Devolver el objeto creado
return dataTable;

}



/// <summary>
/// Métod encargado de recorrer el DataTable y asignar propiedades al objeto
/// </summary>
/// <returns>Una lista de objetos T</returns>

public static List<T> DataTableToLista(DataTable tabla)

{

List<T> lista = new List<T>();

T elemento;

for (int i = 0; i < tabla.Rows.Count; i++)

{

// Información del tipo de datos de los elementos del List

Type itemsType = typeof(T);

elemento = new T();



foreach (PropertyInfo prop in itemsType.GetProperties())

{

//Establecemos cada una de las propiedades

prop.SetValue(elemento,ValorDefault(tabla.Rows[i][prop.Name]), null);

}

lista.Add(elemento);



}

return lista;

}



//Esta parte hay que buscar hacerla de una mejor modo
/// <summary>
/// Método que se encarga de validar los DBNull y convertirlos en una cadena vacia
/// </summary>
/// <returns>El mismo objeto de entrada validado</returns>

private static object ValorDefault(object objeto)

{

if (objeto == System.DBNull.Value)

return "";

else

return objeto;

}

}



p>


Como utilizarla:



MiTipo objParte;

List<MiTipo> listaParte = new List<MiTipo>();




DataTable dataTable = Convertidor<MiTipo>.ListaToDatatable(listaParte);

List<MiTipo> lista = Convertidor<MiTipo>.DataTableToLista(dataTable);





Saludos a todos espero les sirva

3 comentarios:

Ale dijo...

Ehmmm este.... este.... no entendí nada! :)

Anónimo dijo...

Si tengo una clase que yo cree, por ejemplo Ciudad, entonces no me funciona, q tengo q hacer alli ??

MYSTICODF dijo...

Excelente me hiciste un mega paro muchas gracias. ¬¬ y ese que no entendió nada que onda