2010-11-16 9 views
8

Acabo de descubrir LINQ así que sea comprensivo conmigo por favor! :-)LINQ para asignar una tabla de datos en una lista <MyObject>

¡Así que! Tengo un nivel de datos que me proporciona datatables y quiero convertirlos en listas de objetos. Estos objetos se definen en una capa DTO específica (Objetos de transferencia de datos).

¿Cómo puedo mapear cada fila de mi datatable en objetos y poner todos los objetos en una lista? (hoy lo hago campo "manual" tras campo) ¿Es posible con LINQ? ¿He oído hablar de LINQ2Entities? estoy en lo correcto?

Gracias para ayudar a un principiante a entender ...

Respuesta

19

Si los objetos no es demasiado complejo puede utilizar esta:

public static class DataTableExtensions 
{ 
    public static IList<T> ToList<T>(this DataTable table) where T : new() 
    { 
     IList<PropertyInfo> properties = typeof(T).GetProperties().ToList(); 
     IList<T> result = new List<T>(); 

     foreach (var row in table.Rows) 
     { 
     var item = CreateItemFromRow<T>((DataRow)row, properties); 
     result.Add(item); 
     } 

     return result; 
    } 

    private static T CreateItemFromRow<T>(DataRow row, IList<PropertyInfo> properties) where T : new() 
    { 
     T item = new T(); 
     foreach (var property in properties) 
     { 
      property.SetValue(item, row[property.Name], null); 
     } 
     return item; 
    } 
} 

Con eso en su lugar ahora se puede escribir: var list = YourDataTable.ToList<YourEntityType>().

Puede leer sobre ello aquí: http://blog.tomasjansson.com/convert-datatable-to-generic-list-extension/

y es una respuesta a una pregunta anterior: Convert DataTable to Generic List in C#

EDIT: Debo añadir que esto no se LINQ, pero algunos métodos de extensión a DataTable Escribí. Además, está trabajando con la convención de que las propiedades en el objeto con el que está mapeando tienen el mismo nombre que en DataTable. Por supuesto, esto podría extenderse para leer atributos en las propiedades o el método en sí podría tomar un simple Dictionary<string,string> que podría usarse para hacer la asignación. También podría ampliarlo con alguna funcionalidad que tome un params string[] excludeProperties que podría usarse para excluir algunas de las propiedades.

+0

Excelente, parece que es exactamente lo que quiero hacer! ¿Pero es una clase que tengo que escribir? ¿Por qué DataTableExtensions no hereda de DataTable? – bAN

+0

No hereda, ya que es un método de extensión, por lo que funciona para todos los DataTables. El código que proporcioné es solo algo que armé para mis necesidades, es posible que necesite agregar funcionalidades adicionales como verificación nula y la parte que escribí en la sección ** EDITAR **. Simplemente incluya su espacio de nombres de extensión en el archivo que desea usar y debería funcionar ... igual que la magia :) Además, si responde su interrogante se responde. –

+0

¡Tienes razón, es simplemente mágico! :-) – bAN

0

es mejor Comprobar si la columna existe en la fila para hacer la asignación de otra manera arrojará una excepción, en mi caso tengo dos objetos, uno de ellos tiene más propiedades que el otro con el mismo nombre y tipo de datos

private static T CreateItemFromRow<T>(DataRow row, IList<PropertyInfo> properties) where T : new() 
    { 
     T item = new T(); 
     foreach (var property in properties) 
     { 
      if (row.Table.Columns.Contains(property.Name)) 
      { 
      property.SetValue(item, row[property.Name], null); 
      } 
     } 
     return item; 
    } 
Cuestiones relacionadas