2010-11-16 24 views
8

Właśnie odkrywam LINQ, więc bądź dla mnie kompleksowy, proszę! :-)LINQ do mapowania datatable na listę <MyObject>

Tak! Mam warstwę danych, która dostarcza mi dane i chcę je przekształcić w listy obiektów. Obiekty te są zdefiniowane w spowiedzialnym DTO warstwy (Obiekty transferu danych).

Jak mogę odwzorować wszystkie wiersze z moich datatable na obiekty i umieścić wszystkie obiekty na liście? (dziś robię to "ręcznie" pole po polu) Czy to możliwe z LINQ? Słyszałem o LINQ2Entities? czy mam rację?

Dzięki pomóc początkującym zrozumieć ...

Odpowiedz

19

Jeżeli obiekty nie jest zbyt skomplikowane, można użyć to:

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

Mając to na miejscu można teraz napisać: var list = YourDataTable.ToList<YourEntityType>().

Można o tym przeczytać tutaj: http://blog.tomasjansson.com/convert-datatable-to-generic-list-extension/

I to jest odpowiedź na poprzednie pytanie: Convert DataTable to Generic List in C#

EDIT: należy dodać, że to nie jest LINQ, ale niektóre metody rozszerzenie do DataTable Napisałem. Ponadto działa zgodnie z konwencją, że właściwości obiektu, który mapujesz, mają taką samą nazwę jak w DataTable. Oczywiście można to rozszerzyć, aby odczytać atrybuty na właściwościach lub sama metoda może zająć proste Dictionary<string,string>, które można wykorzystać do mapowania. Można również rozszerzyć go o niektóre funkcje, które wymagają params string[] excludeProperties, które mogą być używane do wykluczania niektórych właściwości.

+0

Dobrze, wygląda na to, że właśnie to chcę robić! Ale czy jest to klasa, którą muszę napisać? dlaczego DataTableExtensions nie dziedziczy po DataTable? – bAN

+0

Nie dziedziczy, ponieważ jest metodą rozszerzenia, więc działa dla wszystkich DataTables. Podany przeze mnie kod jest po prostu czymś, co skompilowałem dla moich potrzeb, może być konieczne dodanie dodatkowej funkcjonalności, takiej jak kontrola zerowa i część, którą napisałem w sekcji ** EDYCJA **. Wystarczy dodać obszar nazw rozszerzeń do pliku, z którego chcesz go użyć i powinien działać ... tak jak magia :) Ponadto, jeśli odpowiedź na twoje pytanie jest w odpowiedzi. –

+0

Masz rację, to tylko magiczne! :-) – bAN

0

lepiej jest sprawdzić, czy kolumna istnieje w wierszu, aby wykonać mapowanie w inny sposób spowoduje wyjątek, w moim przypadku mam dwa obiekty, jeden z nich ma więcej właściwości niż drugi o tej samej nazwie i typie danych

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