Как преобразовать DataTable в общий список?

В настоящее время я использую:

DataTable dt = CreateDataTableInSomeWay();

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

Есть ли лучший / волшебный способ?

Чего вы пытаетесь достичь со списком, чего не можете сделать с помощью DataRowCollection?

Jason Kealey 16.10.2008 17:25

Моя опаздывает, но надежда будет полезна. Рабочее решение..stackoverflow.com/a/58607820/9048996

Thameem 29.10.2019 15:53
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
192
2
521 712
27
Перейти к ответу Данный вопрос помечен как решенный

Ответы 27

Вы могли бы использовать

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

dt.Select() вернет все строки в вашей таблице в виде массива строк данных, а конструктор List принимает этот массив объектов в качестве аргумента для первоначального заполнения вашего списка.

Select () не требует никаких параметров. Перегрузка без параметров вернет все строки.

Kon 16.10.2008 17:29

С C# 3.0 и System.Data.DataSetExtensions.dll,

List<DataRow> rows = table.Rows.Cast<DataRow>().ToList();

это повысило производительность за счет простого использования foreach вместо потока данных на 50%.

lloydom 24.02.2012 14:04
Ответ принят как подходящий

Если вы используете .NET 3.5, вы можете использовать DataTableExtensions.AsEnumerable (метод расширения), а затем, если вам действительно нужен List<DataRow> вместо IEnumerable<DataRow>, вы можете вызвать Enumerable.ToList:

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

или же

using System.Linq;
...
List<DataRow> list = dt.AsEnumerable().ToList();

как преобразовать этот list в json.

ACP 14.08.2010 09:50

@Pandiya: Существуют различные способы преобразования данных в JSON в .NET. Лично я всегда использовал библиотеку JSON.NET, но есть и другие подходы.

Jon Skeet 14.08.2010 11:33
stackoverflow.com/questions/3482261/…
ACP 14.08.2010 11:39

@Jon Skeet: я хочу получить значение в DataRow. Есть ли способ? Вместо того, чтобы получать как list.ItemArray [0].

Ramesh Durai 06.09.2012 17:24

@Jon, к сведению: dt.AsEnumerable (). ToList () 'System.Data.EnumerableRowCollecti‌ на <System.Data.DataRow>' не содержит определения для 'ToList'

Pradip 11.01.2016 17:29

@BabekoofCoder: Тогда вам понадобится using System.Linq; как обычно для LINQ. В этот момент все должно быть в порядке. (Я добавил это в ответ.)

Jon Skeet 11.01.2016 17:41

что, если я хочу преобразовать его в общий список моего настраиваемого типа? List<MyType> = ?? Можно ли это сделать?

user20358 11.01.2016 18:37

Есть ли версия этого для UWP? Я не могу использовать system.data.DataSetExtensions в приложении UWP ... или DataTableExtensions

Allstar 23.06.2020 17:26

@Allstar: Боюсь, я не использовал UWP для чего-либо с DataTables.

Jon Skeet 23.06.2020 17:35

@JonSkeet, спасибо, хотя я только что добрался до этого. Добавьте пакет nuget System.Data.DataSetExtensions ... затем он попадает в уже упоминавшееся пространство имен system.data ... которое меня / запутало

Allstar 23.06.2020 17:45

.AsEnumerable () существует в .net core 2.0 и выше. stackoverflow.com/questions/3949302/…

Sponsor 22.01.2021 12:58

@ Спонсор: Да, но не в .NET 3.0 и ниже - .NET Core 2.0 появился много позже, чем .NET 3.5. Обратите внимание, что этот ответ был написан в 2008 году.

Jon Skeet 22.01.2021 16:52

Более «волшебный» способ, не требующий .NET 3.5.

Если, например, DBDatatable возвращал один столбец Guids (уникальный идентификатор в SQL), вы могли бы использовать:

Dim gList As New List(Of Guid)
gList.AddRange(DirectCast(DBDataTable.Select(), IEnumerable(Of Guid)))

DataTable.Select() не отображает строки в том порядке, в котором они присутствовали в таблице данных.

Если порядок важен, я считаю, что итерация по коллекции datarow и формирование списка - это правильный путь, или вы также можете использовать перегрузку DataTable.Select(string filterexpression, string sort).

Но эта перегрузка может не обрабатывать весь порядок (например, порядок за случаем ...), который предоставляет SQL.

Опять же, используя 3.5, вы можете сделать это так:

dt.Select().ToList()

BRGDS

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();

Приведенный выше код может не работать bcs. dt.Rows не реализовал AsEnumerable. Это можно исправить следующим образом: emp = (из строки DataRow в dt.AsEnumerable () выберите нового сотрудника {_FirstName = row ["FirstName"]. ToString (), _LastName = row ["Last_Name"]. ToString ()}) .Составлять список();

Navin Pandit 25.03.2020 17:59

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();

Если вам просто нужен список значений из поля int "ID", вы можете использовать ...

List<int> ids = (from row in dt.AsEnumerable() select Convert.ToInt32(row["ID"])).ToList();

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

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

Вот метод расширения DataTable, который преобразует DataTable в общий список.

https://gist.github.com/gaui/a0a615029f1327296cf8

Использование:

List<Employee> emp = dtTable.DataTableToList<Employee>();

Это сработало для меня: Требуется хотя бы .Net Framework 3.5, Код ниже отображает DataRow, преобразованный в Generic.IEnumerable, comboBox1 используется для лучшей иллюстрации.

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;

Я добавил некоторые изменения в код из этого ответа (https://stackoverflow.com/a/24588210/4489664), потому что для типов, допускающих значение NULL, он вернет исключение

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

Я удалил класс, потому что он тоже может работать со структурой.

Mickey Perlstein 09.08.2017 12:49

Это работает очень хорошо, хорошая работа. Если кто-то хочет поиграть с кодом, я создал скрипт .net по этой ссылке: dotnetfiddle.net/mTKevy

Almenon 25.07.2018 07:05

@Almenon Я добавил небольшую модификацию, это должно немного повысить производительность

Bondaryuk Vladimir 27.07.2018 12:27

Используйте пространство имен System.Data, тогда вы получите .AsEnumerable().

Вы можете создать функцию расширения как:

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>();

Не работает - см. dotnetfiddle.net/I22r2c. Также следует отметить, что использование Reflection медленное и не рекомендуется для кода, критичного к производительности.

Almenon 25.07.2018 06:55

Вам необходимо добавить информацию о типе данных для столбцов. DataTable dt = новый DataTable (); dt.Columns.Add ("идентификатор", typeof (Int32)); dt.Columns.Add ("имя", typeof (String)); dt.Columns.Add ("foo", typeof (DateTime)); for (int i = 0; i <= 1000; i ++) {dt.Rows.Add (i, "foo", DateTime.Now);}

Rahul Garg 25.07.2018 13:56

Выход

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", "[email protected]", DateTime.Now.ToString());
    table.Rows.Add(50, "luci", "[email protected]", DateTime.Now.ToString());
    table.Rows.Add(10, "Andrey", "[email protected]", DateTime.Now.ToString());
    table.Rows.Add(21, "Michael", "[email protected]", DateTime.Now.ToString());
    table.Rows.Add(100, "Steven", "[email protected]", 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();
}[][1]

</asp:GridView>
</div>

Мы можем использовать общий метод для преобразования DataTable в List вместо ручного преобразования DataTable в List.

Примечание: DataTableColumnName и TypePropertyName должны быть одинаковыми.

Вызовите метод ниже:

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

        /* 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.

Спасибо за Ваш ответ. Было бы здорово, если бы вы также добавили в свой код краткое объяснение и несколько комментариев. Это поможет людям лучше понять ваш ответ.

Andre Hofmeister 30.01.2018 12:57

Вы можете использовать общий метод, подобный этому, для данных в общий список

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

Преобразование DataTable в общий 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;
}

Используйте расширение:

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
}

Чтобы назначить строки DataTable общему списку класса

  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();

Самый простой способ преобразования DataTable в общий список классов

с помощью Newtonsoft.Json;

var json = JsonConvert.SerializeObject(dataTable);
var model = JsonConvert.DeserializeObject<List<ClassName>>(json);

вы можете использовать следующие две общие функции

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

и используйте его следующим образом

List<StudentScanExamsDTO> studentDetails = ConvertDataTable<StudentScanExamsDTO>(dt);

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();

Ссылка на рабочий Пример DotNetFiddle

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

}

Если кто-то хочет создать настраиваемую функцию для преобразования данных в список

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

Если мы выполним приведенный выше код, метод Foreach завершится через 56 мс, а для linq - 101 мс (для 1000 записей). Так что лучше использовать метод Foreach. Источник: Способы преобразования Datatable в список в C# (с примером теста производительности)

Другие вопросы по теме