205

Currently, I'm using:

DataTable dt = CreateDataTableInSomeWay();

List<DataRow> list = new List<DataRow>(); 
foreach (DataRow dr in dt.Rows)
{
    list.Add(dr);
}

Is there a better/magic way?

Iain Holder
  • 14,172
  • 10
  • 66
  • 86

29 Answers29

301

If you're using .NET 3.5, you can use DataTableExtensions.AsEnumerable (an extension method) and then if you really need a List<DataRow> instead of just IEnumerable<DataRow> you can call Enumerable.ToList:

IEnumerable<DataRow> sequence = dt.AsEnumerable();

or

using System.Linq;
...
List<DataRow> list = dt.AsEnumerable().ToList();
Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • 1
    how to convert this `list` to json. – ACP Aug 14 '10 at 05:50
  • 6
    @Pandiya: There are various ways of converting data into JSON in .NET. Personally I've always used the JSON.NET library, but there are other approaches too. – Jon Skeet Aug 14 '10 at 07:33
  • http://stackoverflow.com/questions/3482261/how-to-convert-c-generic-list-to-json-using-json-net – ACP Aug 14 '10 at 07:39
  • 1
    @Jon Skeet: I want to get the value in DataRow. Is there any method? Instead of getting like list.ItemArray[0]. – Ramesh Durai Sep 06 '12 at 13:24
  • @Jon, FYI : dt.AsEnumerable().ToList()'System.Data.EnumerableRowCollection' does not contain a definition for 'ToList' – Pradip Jan 11 '16 at 14:29
  • @BabekoofCoder: Then you need `using System.Linq;` as normal for LINQ. It should be fine at that point. (I've added that into the answer.) – Jon Skeet Jan 11 '16 at 14:41
  • what if I want to convert it into a generic list of my custom type? `List = ?? ` Can this be done ? – user20358 Jan 11 '16 at 15:37
  • Is there a version of this for UWP? I can't get using system.data.DataSetExtensions in a UWP app... or DataTableExtensions – Allstar Jun 23 '20 at 14:26
  • @Allstar: I haven't used UWP for doing anything with DataTables, I'm afraid. – Jon Skeet Jun 23 '20 at 14:35
  • @JonSkeet , thanks though I just got to it. Add the System.Data.DataSetExtensions nuget package... it then falls under the, already referenced, system.data namespace... which got me/confused – Allstar Jun 23 '20 at 14:45
  • .AsEnumerable() exists in .net core 2.0 and above. https://stackoverflow.com/questions/3949302/linq-to-dataset-datatable-asenumerable-not-recognized – Sponsor Jan 22 '21 at 09:58
  • 1
    @Sponsor: Yes, but not in .NET 3.0 and below - .NET Core 2.0 came *much* later than .NET 3.5. Note that this answer was written in 2008. – Jon Skeet Jan 22 '21 at 13:52
70
List<Employee> emp = new List<Employee>();

//Maintaining DataTable on ViewState
//For Demo only

DataTable dt = ViewState["CurrentEmp"] as DataTable;

//read data from DataTable 
//using lamdaexpression


emp = (from DataRow row in dt.Rows

   select new Employee
   {
       _FirstName = row["FirstName"].ToString(),
       _LastName = row["Last_Name"].ToString()

   }).ToList();
musefan
  • 47,875
  • 21
  • 135
  • 185
darshan pandya
  • 701
  • 5
  • 2
  • 1
    Above code may not work bcs. dt.Rows has not implemented 'AsEnumerable'. This can be corrected as below: emp = (from DataRow row in dt.AsEnumerable() select new Employee { _FirstName = row["FirstName"].ToString(), _LastName = row["Last_Name"].ToString() }).ToList(); – Navin Pandit Mar 25 '20 at 14:59
41

With C# 3.0 and System.Data.DataSetExtensions.dll,

List<DataRow> rows = table.Rows.Cast<DataRow>().ToList();
Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
36

You could use

List<DataRow> list = new List<DataRow>(dt.Select());

dt.Select() will return all rows in your table, as an array of datarows, and the List constructor accepts that array of objects as an argument to initially fill your list with.

Kibbee
  • 65,369
  • 27
  • 142
  • 182
  • Select() doesn't need any parameters. The parameterless overload would return all rows. – Kon Oct 16 '08 at 13:29
18

If you just want a list of values from the "ID" int field returned, you could use...

List<int> ids = (from row in dt.AsEnumerable() select Convert.ToInt32(row["ID"])).ToList();
Stuart
  • 671
  • 7
  • 20
18

You can create a extension function as :

public static List<T> ToListof<T>(this DataTable dt)
{
    const BindingFlags flags = BindingFlags.Public | BindingFlags.Instance;
    var columnNames = dt.Columns.Cast<DataColumn>()
        .Select(c => c.ColumnName)
        .ToList();
    var objectProperties = typeof(T).GetProperties(flags);
    var targetList = dt.AsEnumerable().Select(dataRow =>
    {
        var instanceOfT = Activator.CreateInstance<T>();

        foreach (var properties in objectProperties.Where(properties => columnNames.Contains(properties.Name) && dataRow[properties.Name] != DBNull.Value))
        {
            properties.SetValue(instanceOfT, dataRow[properties.Name], null);
        }
        return instanceOfT;
    }).ToList();

    return targetList;
}


var output = yourDataInstance.ToListof<targetModelType>();
Barney
  • 2,355
  • 3
  • 22
  • 37
Rahul Garg
  • 4,069
  • 1
  • 34
  • 31
  • Doesn't work - see https://dotnetfiddle.net/I22r2c It should also be noted that using Reflection is slow and not reccomended in performance critical code. – Almenon Jul 25 '18 at 03:55
  • You need to add data type information for columns. DataTable dt = new DataTable(); dt.Columns.Add("id",typeof(Int32 )); dt.Columns.Add("name",typeof(String)); dt.Columns.Add("foo",typeof(DateTime )); for(int i=0;i<=1000;i++){dt.Rows.Add(i, "foo", DateTime.Now);} – Rahul Garg Jul 25 '18 at 10:56
15

I have added some modification to the code from this answer (https://stackoverflow.com/a/24588210/4489664) because for nullable Types it will return exception

public static List<T> DataTableToList<T>(this DataTable table) where T: new()
{
    List<T> list = new List<T>();
    var typeProperties = typeof(T).GetProperties().Select(propertyInfo => new
        {
            PropertyInfo = propertyInfo,
            Type = Nullable.GetUnderlyingType(propertyInfo.PropertyType) ?? propertyInfo.PropertyType
        }).ToList();

    foreach (var row in table.Rows.Cast<DataRow>())
    {
        T obj = new T();
        foreach (var typeProperty in typeProperties)
        {
            object value = row[typeProperty.PropertyInfo.Name];
            object safeValue = value == null || DBNull.Value.Equals(value)
                ? null
                : Convert.ChangeType(value, typeProperty.Type);

            typeProperty.PropertyInfo.SetValue(obj, safeValue, null);
        }
        list.Add(obj);
    }
    return list;
}
11
using System.Data;


var myEnumerable = myDataTable.AsEnumerable();

List<MyClass> myClassList =
    (from item in myEnumerable
     select new MyClass{
         MyClassProperty1 = item.Field<string>("DataTableColumnName1"),
         MyClassProperty2 = item.Field<string>("DataTableColumnName2")
    }).ToList();
Morteza
  • 2,378
  • 5
  • 26
  • 37
6
// this is better suited for expensive object creation/initialization
IEnumerable<Employee> ParseEmployeeTable(DataTable dtEmployees)
{
    var employees = new ConcurrentBag<Employee>();

    Parallel.ForEach(dtEmployees.AsEnumerable(), (dr) =>
    {
        employees.Add(new Employee() 
        {
            _FirstName = dr["FirstName"].ToString(),
            _LastName = dr["Last_Name"].ToString()
        });
    });

    return employees;
}
Nathan
  • 153
  • 1
  • 6
6

Again, using 3.5 you may do it like:

dt.Select().ToList()

BRGDS

Guilherme Duarte
  • 3,371
  • 1
  • 28
  • 35
5

The Easiest way of Converting the DataTable into the Generic list of class

using Newtonsoft.Json;

var json = JsonConvert.SerializeObject(dataTable);
var model = JsonConvert.DeserializeObject<List<ClassName>>(json);
4
DataTable dt;   // datatable should contains datacolumns with Id,Name

List<Employee> employeeList=new List<Employee>();  // Employee should contain  EmployeeId, EmployeeName as properties

foreach (DataRow dr in dt.Rows)
{
    employeeList.Add(new Employee{EmployeeId=dr.Id,EmplooyeeName=dr.Name});
}
Darshan Dave
  • 645
  • 2
  • 9
  • 32
4

A more 'magic' way, and doesn't need .NET 3.5.

If, for example, DBDatatable was returning a single column of Guids (uniqueidentifier in SQL) then you could use:

Dim gList As New List(Of Guid)
gList.AddRange(DirectCast(DBDataTable.Select(), IEnumerable(Of Guid)))
Barney
  • 2,355
  • 3
  • 22
  • 37
3

DataTable.Select() doesnt give the Rows in the order they were present in the datatable.

If order is important I feel iterating over the datarow collection and forming a List is the right way to go or you could also use overload of DataTable.Select(string filterexpression, string sort).

But this overload may not handle all the ordering (like order by case ...) that SQL provides.

Mutix
  • 4,196
  • 1
  • 27
  • 39
user_v
  • 9,628
  • 4
  • 40
  • 32
2
        /* This is a generic method that will convert any type of DataTable to a List 
         * 
         * 
         * Example :    List< Student > studentDetails = new List< Student >();  
         *              studentDetails = ConvertDataTable< Student >(dt);  
         *
         * Warning : In this case the DataTable column's name and class property name
         *           should be the same otherwise this function will not work properly
         */

The following are the two functions in which if we pass a DataTable and a user defined class. It will then return the List of that class with the DataTable data.

        public static List<T> ConvertDataTable<T>(DataTable dt)
        {
            List<T> data = new List<T>();
            foreach (DataRow row in dt.Rows)
            {
                T item = GetItem<T>(row);
                data.Add(item);
            }
            return data;
        }


        private static T GetItem<T>(DataRow dr)
        {
            Type temp = typeof(T);
            T obj = Activator.CreateInstance<T>();

            foreach (DataColumn column in dr.Table.Columns)
            {
                foreach (PropertyInfo pro in temp.GetProperties())
                {
                   //in case you have a enum/GUID datatype in your model
                   //We will check field's dataType, and convert the value in it.
                    if (pro.Name == column.ColumnName){                
                    try
                    {
                        var convertedValue = GetValueByDataType(pro.PropertyType, dr[column.ColumnName]);
                        pro.SetValue(obj, convertedValue, null);
                    }
                    catch (Exception e)
                    {         
                       //ex handle code                   
                        throw;
                    }
                        //pro.SetValue(obj, dr[column.ColumnName], null);
                }
                    else
                        continue;
                }
            }
            return obj;
        }

This method will check the datatype of field, and convert dataTable value in to that datatype.

    private static object GetValueByDataType(Type propertyType, object o)
    {
        if (o.ToString() == "null")
        {
            return null;
        }
        if (propertyType == (typeof(Guid)) || propertyType == typeof(Guid?))
        {
            return Guid.Parse(o.ToString());
        }
        else if (propertyType == typeof(int) || propertyType.IsEnum) 
        {
            return Convert.ToInt32(o);
        }
        else if (propertyType == typeof(decimal) )
        {
            return Convert.ToDecimal(o);
        }
        else if (propertyType == typeof(long))
        {
            return Convert.ToInt64(o);
        }
        else if (propertyType == typeof(bool) || propertyType == typeof(bool?))
        {
            return Convert.ToBoolean(o);
        }
        else if (propertyType == typeof(DateTime) || propertyType == typeof(DateTime?))
        {
            return Convert.ToDateTime(o);
        }
        return o.ToString();
    }

To call the preceding method, use the following syntax:

List< Student > studentDetails = new List< Student >();  
studentDetails = ConvertDataTable< Student >(dt); 

Change the Student class name and dt value based on your requirements. In this case the DataTable column's name and class property name should be the same otherwise this function will not work properly.

Saurin
  • 1,650
  • 1
  • 10
  • 8
  • 1
    Thanks for your answer. It would be great if you would also add a short explanation and a few comments to your code. This helps people to understand your answer better. – Andre Hofmeister Jan 30 '18 at 09:57
2
lPerson = dt.AsEnumerable().Select(s => new Person()
        {
            Name = s.Field<string>("Name"),
            SurName = s.Field<string>("SurName"),
            Age = s.Field<int>("Age"),
            InsertDate = s.Field<DateTime>("InsertDate")
        }).ToList();

Link to working DotNetFiddle Example

    using System;
    using System.Collections.Generic;   
    using System.Data;
    using System.Linq;
    using System.Data.DataSetExtensions;

    public static void Main()
    {
        DataTable dt = new DataTable();
        dt.Columns.Add("Name", typeof(string));
        dt.Columns.Add("SurName", typeof(string));
        dt.Columns.Add("Age", typeof(int));
        dt.Columns.Add("InsertDate", typeof(DateTime));

        var row1= dt.NewRow();
        row1["Name"] = "Adam";
        row1["SurName"] = "Adam";
        row1["Age"] = 20;
        row1["InsertDate"] = new DateTime(2020, 1, 1);
        dt.Rows.Add(row1);

        var row2 = dt.NewRow();
        row2["Name"] = "John";
        row2["SurName"] = "Smith";
        row2["Age"] = 25;
        row2["InsertDate"] = new DateTime(2020, 3, 12);
        dt.Rows.Add(row2);

        var row3 = dt.NewRow();
        row3["Name"] = "Jack";
        row3["SurName"] = "Strong";
        row3["Age"] = 32;
        row3["InsertDate"] = new DateTime(2020, 5, 20);
        dt.Rows.Add(row3);

        List<Person> lPerson = new List<Person>();
        lPerson = dt.AsEnumerable().Select(s => new Person()
        {
            Name = s.Field<string>("Name"),
            SurName = s.Field<string>("SurName"),
            Age = s.Field<int>("Age"),
            InsertDate = s.Field<DateTime>("InsertDate")
        }).ToList();
        
        foreach(Person pers in lPerson)
        {
            Console.WriteLine("{0} {1} {2} {3}", pers.Name, pers.SurName, pers.Age, pers.InsertDate);
        }
    }   
    
    public class Person
    {
        public string Name { get; set; }
        public string SurName { get; set; }
        public int Age { get; set; }
        public DateTime InsertDate { get; set; }
    }
}
Harshad Pansuriya
  • 20,189
  • 8
  • 67
  • 95
mr R
  • 997
  • 2
  • 12
  • 25
1

Use System.Data namespace then you will get .AsEnumerable().

Jakub Arnold
  • 85,596
  • 89
  • 230
  • 327
rajashekar
  • 21
  • 1
1

If anyone want's to create custom function to convert datatable to list

class Program
{
    static void Main(string[] args)
    {
        DataTable table = GetDataTable();
        var sw = new Stopwatch();

        sw.Start();
        LinqMethod(table);
        sw.Stop();
        Console.WriteLine("Elapsed time for Linq Method={0}", sw.ElapsedMilliseconds);

        sw.Reset();

        sw.Start();
        ForEachMethod(table);
        sw.Stop();
        Console.WriteLine("Elapsed time for Foreach method={0}", sw.ElapsedMilliseconds);

        Console.ReadKey();
    }

    private static DataTable GetDataTable()
    {
        var table = new DataTable();
        table.Columns.Add("ID", typeof(double));
        table.Columns.Add("CategoryName", typeof(string));
        table.Columns.Add("Active", typeof(double));

        var rand = new Random();

        for (int i = 0; i < 100000; i++)
        {
            table.Rows.Add(i, "name" + i,  rand.Next(0, 2));
        }
        return table;
    }

    private static void LinqMethod(DataTable table)
    {
        var list = table.AsEnumerable()
            .Skip(1)
            .Select(dr =>
                new Category
                {
                    Id = Convert.ToInt32(dr.Field<double>("ID")),
                    CategoryName = dr.Field<string>("CategoryName"),                      
                    IsActive =
                            dr.Field<double>("Active") == 1 ? true : false
                }).ToList();
    }
    private static void ForEachMethod(DataTable table)
    {
        var categoryList = new List<Category>(table.Rows.Count);
        foreach (DataRow row in table.Rows)
        {
            var values = row.ItemArray;
            var category = new Category()
            {
                Id = Convert.ToInt32(values[0]),
                CategoryName = Convert.ToString(values[1]),                   
                IsActive = (double)values[2] == 1 ? true : false
            };
            categoryList.Add(category);
        }
    }

    private class Category
    {
        public int Id { get; set; }
        public string CategoryName { get; set; }
        public bool IsActive { get; set; }
    }
}

If we execute above code, Foreach method finishes in 56ms while linq one takes 101ms ( for 1000 records). So Foreach method is better to use. Source:Ways to Convert Datatable to List in C# (with performance test example)

Vikas Lalwani
  • 1,041
  • 18
  • 29
0

This worked for me: Need at least .Net Framework 3.5, Code below displays DataRow turned to Generic.IEnumerable, comboBox1 has been used for a better illustration.

using System.Linq;

DataTable dt = new DataTable();            
dt = myClass.myMethod();                 
List<object> list = (from row in dt.AsEnumerable() select (row["name"])).ToList();
comboBox1.DataSource = list;
Levi
  • 21
  • 1
0

Output

public class ModelUser
{
    #region Model

    private string _username;
    private string _userpassword;
    private string _useremail;
    private int _userid;

    /// <summary>
    /// 
    /// </summary>
    public int userid
    {
        set { _userid = value; }
        get { return _userid; }
    }


    /// <summary>
    /// 
    /// </summary>

    public string username
    {
        set { _username = value; }
        get { return _username; }
    }

    /// <summary>
    /// 
    /// </summary>
    public string useremail
    {
        set { _useremail = value; }
        get { return _useremail; }
    }

    /// <summary>
    /// 
    /// </summary>
    public string userpassword
    {
        set { _userpassword = value; }
        get { return _userpassword; }
    }
    #endregion Model
}

public List<ModelUser> DataTableToList(DataTable dt)
{
    List<ModelUser> modelList = new List<ModelUser>();
    int rowsCount = dt.Rows.Count;
    if (rowsCount > 0)
    {
        ModelUser model;
        for (int n = 0; n < rowsCount; n++)
        {
            model = new ModelUser();

            model.userid = (int)dt.Rows[n]["userid"];
            model.username = dt.Rows[n]["username"].ToString();
            model.useremail = dt.Rows[n]["useremail"].ToString();
            model.userpassword = dt.Rows[n]["userpassword"].ToString();

            modelList.Add(model);
        }
    }
    return modelList;
}

static DataTable GetTable()
{
    // Here we create a DataTable with four columns.
    DataTable table = new DataTable();
    table.Columns.Add("userid", typeof(int));
    table.Columns.Add("username", typeof(string));
    table.Columns.Add("useremail", typeof(string));
    table.Columns.Add("userpassword", typeof(string));

    // Here we add five DataRows.
    table.Rows.Add(25, "Jame", "Jame@hotmail.com", DateTime.Now.ToString());
    table.Rows.Add(50, "luci", "luci@hotmail.com", DateTime.Now.ToString());
    table.Rows.Add(10, "Andrey", "Andrey@hotmail.com", DateTime.Now.ToString());
    table.Rows.Add(21, "Michael", "Michael@hotmail.com", DateTime.Now.ToString());
    table.Rows.Add(100, "Steven", "Steven@hotmail.com", DateTime.Now.ToString());
    return table;
}

protected void Page_Load(object sender, EventArgs e)
{
    List<ModelUser> userList = new List<ModelUser>();

    DataTable dt = GetTable();

    userList = DataTableToList(dt);

    gv.DataSource = userList;
    gv.DataBind();
}[enter image description here][1]

</asp:GridView>
</div>
Nahuel Ianni
  • 3,177
  • 4
  • 23
  • 30
mrtwin
  • 1
0

We can use a Generic Method for converting DataTable to List instead of manually converting a DataTable to List.

Note: DataTable's ColumnName and Type's PropertyName should be same.

Call the below Method:

long result = Utilities.ConvertTo<Student>(dt ,out listStudent);

// Generic Method
public class Utilities
{
    public static long ConvertTo<T>(DataTable table, out List<T> entity)
    {
        long returnCode = -1;
        entity = null;

        if (table == null)
        {
            return -1;
        }

        try
        {
            entity = ConvertTo<T>(table.Rows);
            returnCode = 0;
        }

        catch (Exception ex)
        {
            returnCode = 1000;
        }

        return returnCode;
    }

    static List<T> ConvertTo<T>(DataRowCollection rows)
    {
        List<T> list = null;
        if (rows != null)
        {
            list = new List<T>();

            foreach (DataRow row in rows)
            {
                T item = CreateItem<T>(row);
                list.Add(item);
            }
        }

        return list;
    }

    static T CreateItem<T>(DataRow row)
    {
        string str = string.Empty;
        string strObj = string.Empty;

        T obj = default(T);

        if (row != null)
        {
            obj = Activator.CreateInstance<T>();
            strObj = obj.ToString();
            NameValueCollection objDictionary = new NameValueCollection();

            foreach (DataColumn column in row.Table.Columns)
            {
                PropertyInfo prop = obj.GetType().GetProperty(column.ColumnName);

                if (prop != null)
                {
                    str = column.ColumnName;

                    try
                    {
                        objDictionary.Add(str, row[str].ToString());
                        object value = row[column.ColumnName];
                        Type vType = obj.GetType();

                        if (value == DBNull.Value)
                        {
                            if (vType == typeof(int) || vType == typeof(Int16)
                                                     || vType == typeof(Int32)
                                                     || vType == typeof(Int64)
                                                     || vType == typeof(decimal)
                                                     || vType == typeof(float)
                                                     || vType == typeof(double))
                            {
                                value = 0;
                            }

                            else if (vType == typeof(bool))
                            {
                                value = false;
                            }

                            else if (vType == typeof(DateTime))
                            {
                                value = DateTime.MaxValue;
                            }

                            else
                            {
                                value = null;
                            }

                            prop.SetValue(obj, value, null);
                        }

                        else
                        {
                            prop.SetValue(obj, value, null);
                        }
                    }

                    catch(Exception ex)
                    {

                    }
                }
            }

            PropertyInfo ActionProp = obj.GetType().GetProperty("ActionTemplateValue");

            if (ActionProp != null)
            {
                object ActionValue = objDictionary;
                ActionProp.SetValue(obj, ActionValue, null);
            }
        }

        return obj;
    }
}
user6234613
  • 145
  • 1
  • 1
  • 10
0

You can use a generic method like that for datatable to generic list

public static List<T> DataTableToList<T>(this DataTable table) where T : class, new()
{
    try
    {
        List<T> list = new List<T>();

        foreach (var row in table.AsEnumerable())
        {
            T obj = new T();

            foreach (var prop in obj.GetType().GetProperties())
            {
                try
                {
                    PropertyInfo propertyInfo = obj.GetType().GetProperty(prop.Name);
                    if (propertyInfo.PropertyType.IsEnum)
                    {
                        propertyInfo.SetValue(obj, Enum.Parse(propertyInfo.PropertyType, row[prop.Name].ToString()));
                    }
                    else
                    {
                        propertyInfo.SetValue(obj, Convert.ChangeType(row[prop.Name], propertyInfo.PropertyType), null);
                    }                          
                }
                catch
                {
                    continue;
                }
            }

            list.Add(obj);
        }

        return list;
    }
    catch
    {
        return null;
    }
}
pushkin
  • 9,575
  • 15
  • 51
  • 95
0

Converting DataTable to Generic Dictionary

public static Dictionary<object,IList<dynamic>> DataTable2Dictionary(DataTable dt)
{
    Dictionary<object, IList<dynamic>> dict = new Dictionary<dynamic, IList<dynamic>>();

    foreach(DataColumn column in dt.Columns)
    {
        IList<dynamic> ts = dt.AsEnumerable()
                              .Select(r => r.Field<dynamic>(column.ToString()))
                              .ToList();
        dict.Add(column, ts);
    }
    return dict;
}
barbsan
  • 3,418
  • 11
  • 21
  • 28
Anil
  • 1
  • 1
0

Use Extension :

public static class Extensions
{
    #region Convert Datatable To List
    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;
    }
    #endregion
}
0

you can use following two Generic functions

private static List<T> ConvertDataTable<T>(DataTable dt)
    {
        List<T> data = new List<T>();
        foreach (DataRow row in dt.Rows)
        {
            T item = GetItem<T>(row);
            data.Add(item);
        }
        return data;
    }
    private static T GetItem<T>(DataRow dr)
    {

        Type temp = typeof(T);
        T obj = Activator.CreateInstance<T>();

        foreach (DataColumn column in dr.Table.Columns)
        {
            foreach (PropertyInfo pro in temp.GetProperties())
            {
                if (pro.Name == column.ColumnName)
                    pro.SetValue(obj, dr[column.ColumnName].ToString(), null);
                else
                    continue;
            }
        }
        return obj;
    }

and use it as following

List<StudentScanExamsDTO> studentDetails = ConvertDataTable<StudentScanExamsDTO>(dt);
hosam hemaily
  • 412
  • 5
  • 17
0

try this using Newtonsoft Json:

var json = JsonConvert.SerializeObject(dataTable);
var YourConvertedDataType = JsonConvert.DeserializeObject<YourDataType>(json);
Ali Amini
  • 356
  • 1
  • 3
  • 12
0

To get List of values instead of ItemArray, do this:

List<string> s = dt.AsEnumerable().Select(x => x[0].ToString()).ToList();

The above assumes that you want list of string values from column 0.

Peter Csala
  • 17,736
  • 16
  • 35
  • 75
bobt
  • 1
  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Mar 12 '22 at 07:02
-1

To assign the DataTable rows to the generic List of class

  List<Candidate> temp = new List<Candidate>();//List that holds the Candidate Class,
    //Note:The Candidate class contains RollNo,Name and Department
    //tb is DataTable
    temp = (from DataRow dr in tb.Rows
                        select new Candidate()
                        {
                            RollNO = Convert.ToInt32(dr["RollNO"]),
                            Name = dr["Name"].ToString(),
                            Department = dr["Department"].ToString(),

                        }).ToList();
-1

To convert a dataTable into a generic list, here List<CustomerEntity>, try this code:

List<CustomerEntity> customers = new List<CustomerEntity>();
List<DataRow> rows = dataTable.AsEnumerable().ToList();

rows.ForEach(r =>
    {
        customers.Add(new CustomerEntity()
        {
            Id= r.Field<int>("Id"),
            Name= r.Field<string>("Name"),
            Address= r.Field<string>("Address"),
            Point= r.Field<int>("Point")
        }
    );
    });

or

List<CustomerEntity> customers = dataTable.Rows.OfType<DataRow>()
        .Select(dr => new CustomerEntity
        {
            Id= dr.Field<int>("Id"),
            Name= dr.Field<string>("Name"),
            Address= dr.Field<string>("Address"),
            Point= dr.Field<int>("Point")
        }).ToList();