9

I just discover LINQ so be comprehensive with me please! :-)

So! I have a Data-tier who provide me datatables and i want to convert them into lists of objects. These objects are defined in a spécific layer DTO (Data transfer Objects).

How can I map every rows of my datatable into objects and put the all objects into a list? (today i make it "manually" field after field) Is it possible with LINQ? I've heard about LINQ2Entities? am i right?

Thanks to help a beginner to understand...

bAN
  • 13,375
  • 16
  • 60
  • 93

3 Answers3

21

If the objects is not too complex you can use this:

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

With that in place you can now write: var list = YourDataTable.ToList<YourEntityType>().

You can read about it here: http://blog.tomasjansson.com/convert-datatable-to-generic-list-extension/

And it is an answer to a previous question: Convert DataTable to Generic List in C#

EDIT: I should add that this is not linq, but some extension methods to DataTable I wrote. Also, it is working with the convention that the properties in the object you're mapping with has the same name as in the DataTable. Of course this could be extended to read attributes on the properties or the method itself could take a simple Dictionary<string,string> that could be used to do the mapping. You could also extend it with some functionality that take a params string[] excludeProperties that could be used to exclude some of the properties.

Community
  • 1
  • 1
Tomas Jansson
  • 22,767
  • 13
  • 83
  • 137
  • Excellent, it seems it is exactly what I want to do! But is it a class I have to write? why DataTableExtensions doesn't inherits from DataTable? – bAN Nov 16 '10 at 13:38
  • It doesn't inherit since it is an extension method so it works for all DataTables. The code I provided is just something I put together for my needs, you might need to add extra functionality like null check and the part I wrote in the **EDIT** section. Just include your extension namespace in the file you want to use it and it should work... just like magic :) Also, if it answers your question mark is at answered. – Tomas Jansson Nov 16 '10 at 13:49
  • 1
    As long as you're aware of the convention that properties are mapped against columns you should be just fine. If you need something the other way around, that is, `IList` to `DataTable` I have that on my blog to blog.tomasjansson.com. – Tomas Jansson Nov 16 '10 at 15:45
0

I would suggest reading about The ADO.NET Entity Framework. It supports what you're asking, and the link should provide you with sufficient information and examples :)

There are also plenty of tutorials out there about the topic to get you started.

Julian
  • 20,008
  • 17
  • 77
  • 108
0

it's better to Check if the column exist in the row to do the mapping another way it will throw an exception, in my case I have two objects one of them have more proprieties than the other with the same name and data type

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