Как преобразовать Datatable в список классов c # [duplicate]

Вы можете использовать эту функцию:

func movePageToIndex(pageIndex NSInteger)->() {
    var viewControllers = []
    var direction : UIPageViewControllerNavigationDirection! 
    if (pageIndex < currentIndex) {
        direction = UIPageViewControllerNavigationDirection.Reverse
    } else {
        direction = UIPageViewControllerNavigationDirection.Forward
    }
    viewControllers = @[[self.getItemController(pageIndex)]]

    WEAKSELF weakSelf = self;
    self.pageViewController.setViewControllers:viewControllers direction:direction animated:false completion:nil];
}
153
задан Iain Holder 16 October 2008 в 14:23
поделиться

21 ответ

Если вы используете .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();
233
ответ дан Jon Skeet 18 August 2018 в 23:00
поделиться
  • 1
    как преобразовать этот list в json. – Chendur Pandian 14 August 2010 в 06:50
  • 2
    @Pandiya: Существуют различные способы преобразования данных в JSON в .NET. Лично я всегда использовал библиотеку JSON.NET, но есть и другие подходы. – Jon Skeet 14 August 2010 в 08:33
  • 3
    [Д0] stackoverflow.com/questions/3482261/… – Chendur Pandian 14 August 2010 в 08:39
  • 4
    @Jon Skeet: Я хочу получить значение в DataRow. Есть ли какой-нибудь метод? Вместо получения типа list.ItemArray [0]. – Ramesh Durai 6 September 2012 в 14:24
  • 5
    @Jon, FYI: dt.AsEnumerable (). ToList () 'System.Data.EnumerableRowCollection & lt; System.Data.DataRow & gt;' не содержит определения для 'ToList' – pordi 11 January 2016 в 15:29

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

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>();
11
ответ дан 2 revs, 2 users 74% 18 August 2018 в 23:00
поделиться
  • 1
    Не работает - см. dotnetfiddle.net/I22r2c Следует также отметить, что использование Reflection выполняется медленно и не рекомендуется в критическом критически важном коде. – Almenon 25 July 2018 в 03:55
  • 2
    Вам нужно добавить информацию о типе данных для столбцов. DataTable dt = new DataTable (); dt.Columns.Add ("id", typeof (Int32)); dt.Columns.Add (& Quot; имя & Quot;, TypeOf (строка)); dt.Columns.Add ("foo", typeof (DateTime)); for (int i = 0; i & lt; = 1000; i ++) {dt.Rows.Add (i, "foo", DateTime.Now);} – Rahul Garg 25 July 2018 в 10:56
  • 3
    Работает сейчас. Благодарю. – Almenon 26 July 2018 в 15:26

DataTable.Select() не дает строк в том порядке, в котором они присутствовали в datatable.

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

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

3
ответ дан 3 revs, 2 users 71% 18 August 2018 в 23:00
поделиться

https://www.nuget.org/packages/AD.GenericConversion/

Оформить эту библиотеку для конвертации, вы увидите здесь все типы конверсий:

  1. DataTable to GenericList
  2. Общий тип для DataTable
  3. Json to DataTable, общий список, общий тип
  4. DataTable для Json
0
ответ дан Abhay kumar 18 August 2018 в 23:00
поделиться
  • 1
    Есть ли примеры использования этой библиотеки? – John K. 27 May 2018 в 12:17

Более «волшебный» способ и не нужен .NET 3.5.

Если, например, DBDatatable возвращал один столбец Guides (uniqueidentifier в SQL), тогда вы могли бы использовать :

Dim gList As New List(Of Guid)
gList.AddRange(DirectCast(DBDataTable.Select(), IEnumerable(Of Guid)))
4
ответ дан Barney 18 August 2018 в 23:00
поделиться

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

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;
}
5
ответ дан Bondaryuk Vladimir 18 August 2018 в 23:00
поделиться
  • 1
    Я удалил класс, потому что он тоже может работать со структурой. – Mickey Perlstein 9 August 2017 в 09:49
  • 2
    Это работает очень хорошо, хорошая работа. Если кто-то хочет поиграть с кодом, я создал скрипт .net по этой ссылке: dotnetfiddle.net/mTKevy – Almenon 25 July 2018 в 04:05
  • 3
    @Almenon Я добавил небольшую модификацию, это должно немного увеличить производительность – Bondaryuk Vladimir 27 July 2018 в 09:27
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});
}
2
ответ дан Darshan Dave 18 August 2018 в 23:00
поделиться

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

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

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

List<Employee> emp = dtTable.DataTableToList<Employee>();
2
ответ дан Gaui 18 August 2018 в 23:00
поделиться

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

dt.Select().ToList()

BRGDS

6
ответ дан Guilherme Duarte 18 August 2018 в 23:00
поделиться

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

0
ответ дан Jakub Arnold 18 August 2018 в 23:00
поделиться

Это работало для меня: нужно как минимум .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;
0
ответ дан Levi 18 August 2018 в 23:00
поделиться

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

List<DataRow> rows = table.Rows.Cast<DataRow>().ToList();
33
ответ дан Marc Gravell 18 August 2018 в 23:00
поделиться
  • 1
    это помогло производительности просто использовать foreach над datarow на 50% времени. – lloydom 24 February 2012 в 12:04
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();
9
ответ дан Morteza 18 August 2018 в 23:00
поделиться
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();
59
ответ дан musefan 18 August 2018 в 23:00
поделиться

Выход

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>
0
ответ дан Nahuel Ianni 18 August 2018 в 23:00
поделиться
// 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;
}
4
ответ дан Nathan 18 August 2018 в 23:00
поделиться

Вы можете использовать

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

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

30
ответ дан Raghavendra Devraj 18 August 2018 в 23:00
поделиться
  • 1
    Select () не нуждается ни в каких параметрах. Безпараметрическая перегрузка вернет все строки. – Kon 16 October 2008 в 14:29
  • 2
    Спасибо, отрегулировав мой ответ, чтобы соответствовать вашему предложению – Kibbee 16 October 2008 в 14:30
  • 3
    Это работает и в .Net 2.0 – JPProgrammer 16 October 2015 в 03:37
        /* 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
         */

Ниже перечислены две функции, в которых мы передаем DataTable и определенный пользователем класс. Затем он вернет список этого класса с данными DataTable.

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

Этот метод проверяет тип данных поля и преобразует значение dataTable в этот тип данных.

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

Чтобы вызвать предыдущий метод, используйте следующий синтаксис:

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

Измените имя класса Student и dt, исходя из ваших требований. В этом случае имя столбца DataTable и имя свойства класса должны быть одинаковыми, иначе эта функция не будет работать должным образом.

0
ответ дан Saurin 18 August 2018 в 23:00
поделиться
  • 1
    Спасибо за Ваш ответ. Было бы здорово, если бы вы также добавили короткое объяснение и несколько комментариев к вашему коду. Это помогает людям лучше понять ваш ответ. – hofmeister 30 January 2018 в 10:57

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

List<int> ids = (from row in dt.AsEnumerable() select Convert.ToInt32(row["ID"])).ToList();
11
ответ дан Stuart 18 August 2018 в 23:00
поделиться

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

Примечание: DataTable 's ColumnName и Type 's PropertyName должен быть таким же.

Вызвать ниже Метод:

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;
    }
}
0
ответ дан user6234613 18 August 2018 в 23:00
поделиться
0
ответ дан pushkin 30 October 2018 в 10:42
поделиться
Другие вопросы по тегам:

Похожие вопросы: