Mr. MonoChrome
Mr. MonoChrome

Reputation: 1383

How to deserialize a datatable to list<T>

Im looking for a library(nuget preferably) that converts a datatable with column names matching a generic object, into a list of that object. For example if i have a class:

public class foo{
   public string bar{get;set;}
   public int count{get;set;}
}

And a datatable

+---------+-------+
|   bar   | count |
+---------+-------+
| string1 |     1 |
| string2 |     5 |
+---------+-------+

Be able to call something like

List<foo> foos =DTSerializer.Deserialize<foo>(dt).ToList();

Upvotes: 1

Views: 1615

Answers (2)

Nilesh Kadam
Nilesh Kadam

Reputation: 11

Enhance this extension code for nullable and for

public static List<T> MapTableToList<T>(this DataTable table) where T : new()
{
        List<T> result = new List<T>();
        var Type = typeof(T);

        foreach (DataRow row in table.Rows)
        {
            T item = new T();
            foreach (var property in Type.GetProperties())
            {
                if(table.Columns.IndexOf(property.Name) > -1)
                {
                    if (row[table.Columns[property.Name]] == System.DBNull.Value && property.GetMethod.ReturnType.Name.IndexOf("Nullable") > -1)
                    {
                        property.SetMethod.Invoke(item, new object[] { null });
                    }
                    else
                    {
                        property.SetMethod.Invoke(item, new object[] { row[table.Columns[property.Name]] });
                    }
                }
            }
            result.Add(item);
        }
        return result;
}

Upvotes: 0

Florian Schmidinger
Florian Schmidinger

Reputation: 4692

Think what you need is a little reflection magic rather than serialization:

class Program
{
    static void Main(string[] args)
    {
        DataTable table = new DataTable();
        table.Columns.Add("foo",typeof(string));
        table.Columns.Add("bar",typeof(int));

        table.Rows.Add("row1", 1);
        table.Rows.Add("row2", 2);

        var result = table.MapTableToList<foobar>();

        foreach (foobar item in result)
        {
            Console.WriteLine("{0}:{1}", item.foo, item.bar);
        }

    }
}

class foobar
{
    public string foo { get; set; }
    public int bar { get; set; }
}

public static class ExtensionMethods
{ 
    public static List<T> MapTableToList<T>(this DataTable table) where T : new ()
    {
        List<T> result = new List<T>();
        var Type = typeof(T);

        foreach (DataRow row in table.Rows)
        {
            T item = new T();
            foreach (var property in Type.GetProperties())
            {
                property.SetMethod.Invoke(item, new object[] { row[table.Columns[property.Name]] });
            }
            result.Add(item);
        }

        return result;
    }
}

This will only work if your Column Names match up with the properties though.

Upvotes: 3

Related Questions