2010-11-16 19 views
8

Ho appena scoperto LINQ quindi sii comprensivo con me per favore! :-)LINQ per mappare un datatable in una lista <MyObject>

Quindi! Ho un livello dati che mi fornisce i dati e voglio convertirli in elenchi di oggetti. Questi oggetti sono definiti in uno specifico livello DTO (Data transfer Objects).

Come è possibile mappare ogni riga del mio datatable in oggetti e inserire tutti gli oggetti in un elenco? (oggi lo faccio "manualmente" campo dopo campo) E 'possibile con LINQ? Ho sentito parlare di LINQ2Entities? ho ragione?

Grazie ad aiutare un principiante di capire ...

risposta

19

Se gli oggetti non è troppo complesso è possibile utilizzare questo:

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 questo in luogo ora si può scrivere: var list = YourDataTable.ToList<YourEntityType>().

potete leggere qui: http://blog.tomasjansson.com/convert-datatable-to-generic-list-extension/

Ed è una risposta ad una domanda precedente: Convert DataTable to Generic List in C#

EDIT: devo aggiungere che questo non è LINQ, ma alcuni metodi di estensione a DataTable Scrissi. Inoltre, sta funzionando con la convenzione che le proprietà nell'oggetto con cui stai mappando hanno lo stesso nome di DataTable. Naturalmente questo potrebbe essere esteso per leggere gli attributi sulle proprietà o il metodo stesso potrebbe prendere un semplice Dictionary<string,string> che potrebbe essere usato per fare il mapping. Si potrebbe anche estenderlo con alcune funzionalità che prendono uno params string[] excludeProperties che potrebbe essere utilizzato per escludere alcune proprietà.

+0

Eccellente, sembra proprio quello che voglio fare! Ma è una classe che devo scrivere? perché DataTableExtensions non eredita da DataTable? – bAN

+0

Non eredita poiché è un metodo di estensione, quindi funziona con tutti i DataTable. Il codice che ho fornito è solo qualcosa che ho messo insieme per le mie esigenze, potrebbe essere necessario aggiungere funzionalità extra come il controllo nullo e la parte che ho scritto nella sezione ** EDIT **. Basta includere lo spazio dei nomi delle estensioni nel file che si desidera utilizzare e dovrebbe funzionare ... proprio come per magia :) Inoltre, se risponde, il tuo punto interrogativo ha una risposta. –

+0

Hai ragione è semplicemente magico! :-) – bAN

0

è meglio Controllare se la colonna esiste nella riga per eseguire la mappatura in un altro modo genererà un'eccezione, nel mio caso ho due oggetti uno di loro ha più proprietà rispetto all'altro con lo stesso nome e tipo di dati

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; 
    }