如何将DataTable转换为通用列表?

Iai*_*der 174 c# generics datatable

目前,我正在使用:

DataTable dt = CreateDataTableInSomeWay();

List<DataRow> list = new List<DataRow>(); 
foreach (DataRow dr in dt.Rows)
{
    list.Add(dr);
}
Run Code Online (Sandbox Code Playgroud)

有更好的/神奇的方式吗?

Jon*_*eet 263

如果你使用的是.NET 3.5,你可以使用DataTableExtensions.AsEnumerable(一种扩展方法)然后如果你真的需要一个List<DataRow>而不仅仅是IEnumerable<DataRow>你可以调用Enumerable.ToList:

IEnumerable<DataRow> sequence = dt.AsEnumerable();
Run Code Online (Sandbox Code Playgroud)

要么

using System.Linq;
...
List<DataRow> list = dt.AsEnumerable().ToList();
Run Code Online (Sandbox Code Playgroud)

  • @Pandiya:在.NET中有多种方法可以将数据转换为JSON.我个人总是使用JSON.NET库,但也有其他方法. (6认同)

小智 65

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();
Run Code Online (Sandbox Code Playgroud)


Mar*_*ell 35

使用C#3.0和System.Data.DataSetExtensions.dll,

List<DataRow> rows = table.Rows.Cast<DataRow>().ToList();
Run Code Online (Sandbox Code Playgroud)

  • 这样做有助于通过在数据行上使用foreach 50%的时间来实现性能. (3认同)

Kib*_*bee 31

你可以用

List<DataRow> list = new List<DataRow>(dt.Select());
Run Code Online (Sandbox Code Playgroud)

dt.Select()将返回表中的所有行,作为数据行数组,List构造函数接受该对象数组作为参数,以便最初填充列表.


Rah*_*arg 14

您可以创建扩展功能:

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>();
Run Code Online (Sandbox Code Playgroud)


Stu*_*art 12

如果您只想要返回"ID"int字段中的值列表,则可以使用...

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


Bon*_*mir 11

我已经从这个答案(/sf/answers/1721174731/)添加了一些修改代码,因为对于可为空的类型,它将返回异常

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;
}
Run Code Online (Sandbox Code Playgroud)


Mor*_*eza 9

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();
Run Code Online (Sandbox Code Playgroud)


Gui*_*rte 6

再次使用3.5你可能会这样做:

dt.Select().ToList()
Run Code Online (Sandbox Code Playgroud)

BRGDS


Mag*_*ana 6

将 DataTable 转换为类的通用列表的最简单方法

使用 Newtonsoft.Json;

var json = JsonConvert.SerializeObject(dataTable);
var model = JsonConvert.DeserializeObject<List<ClassName>>(json);
Run Code Online (Sandbox Code Playgroud)


小智 5

一种更“神奇”的方式,并且不需要 .NET 3.5。

例如,如果DBDatatable返回单列 Guid(SQL 中的唯一标识符),那么您可以使用:

Dim gList As New List(Of Guid)
gList.AddRange(DirectCast(DBDataTable.Select(), IEnumerable(Of Guid)))
Run Code Online (Sandbox Code Playgroud)


Nat*_*han 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;
}
Run Code Online (Sandbox Code Playgroud)


Gau*_*aui 5

这是将 DataTable 转换为通用列表的 DataTable 扩展方法。

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

用法:

List<Employee> emp = dtTable.DataTableToList<Employee>();
Run Code Online (Sandbox Code Playgroud)