198

現在、私は使用しています:

DataTable dt = CreateDataTableInSomeWay();

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

より良い/魔法の方法はありますか?

4

27 に答える 27

296

.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();
于 2008-10-16T13:59:01.580 に答える
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();
于 2011-12-15T18:44:19.060 に答える
38

C# 3.0 と System.Data.DataSetExtensions.dll を使用すると、

List<DataRow> rows = table.Rows.Cast<DataRow>().ToList();
于 2008-10-16T13:28:03.530 に答える
34

あなたが使用することができます

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

dt.Select()テーブル内のすべての行をデータ行の配列として返し、Listコンストラクターはそのオブジェクトの配列を引数として受け取り、最初にリストに入力します。

于 2008-10-16T13:26:16.887 に答える
17

次のように拡張機能を作成できます。

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>();
于 2015-04-26T12:21:11.700 に答える
16

「ID」intフィールドの値のリストを返すだけの場合は、...を使用できます。

List<int> ids = (from row in dt.AsEnumerable() select Convert.ToInt32(row["ID"])).ToList();
于 2012-10-10T14:56:46.627 に答える
15

null 許容型の場合は例外が返されるため、この回答 ( https://stackoverflow.com/a/24588210/4489664 )のコードにいくつかの変更を加えました。

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;
}
于 2015-04-14T11:13:04.633 に答える
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();
于 2012-07-31T06:00:38.880 に答える
6

繰り返しますが、3.5 を使用すると、次のようにすることができます。

dt.Select().ToList()

BRGDS

于 2010-03-15T13:17:00.460 に答える
5
// 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;
}
于 2013-07-23T19:59:59.237 に答える
4

より「魔法の」方法であり、.NET 3.5 は必要ありません。

たとえば、DBDatatableGuids (SQL では一意の識別子) の単一の列を返す場合は、次を使用できます。

Dim gList As New List(Of Guid)
gList.AddRange(DirectCast(DBDataTable.Select(), IEnumerable(Of Guid)))
于 2009-03-30T15:59:08.263 に答える
3

DataTable.Select()データテーブルに存在する順序で行を提供しません。

順序が重要な場合は、データ行コレクションを反復処理してリストを作成するのが正しい方法だと思います。または、オーバーロードを使用することもできますDataTable.Select(string filterexpression, string sort)

ただし、このオーバーロードは、SQL が提供するすべての順序付け (ケースごとの順序など) を処理できない場合があります。

于 2009-07-09T09:52:33.660 に答える
3
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});
}
于 2012-12-06T05:47:40.030 に答える
1

System.Data名前空間を使用すると、 が得られ.AsEnumerable()ます。

于 2015-04-20T06:34:21.787 に答える
0

手動で aをに変換DataTableするList代わりに、ジェネリック メソッドを使用して に変換できます。DataTableList

注:DataTableとは同じである必要がありますColumnNameTypePropertyName

以下のメソッドを呼び出します。

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;
    }
}
于 2016-03-10T11:58:18.400 に答える
0

これは私にとってはうまくいきました: 少なくとも.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;
于 2014-09-02T13:26:15.667 に答える
0

誰かがデータテーブルをリストに変換するカスタム関数を作成したい場合

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 メソッドを使用することをお勧めします。出典: C# で Datatable を List に変換する方法 (パフォーマンス テストの例あり)

于 2020-10-23T15:48:22.523 に答える
0

次の2つの汎用関数を使用できます

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);
于 2020-01-29T12:10:16.563 に答える