将DataTable转换为List <T>

Kri*_*s-I 40 .net c# generics datatable

我有一个强类型的DataTable类型MyType,我想转换它List<MyType>.

我怎样才能做到这一点 ?

谢谢.

Yur*_*ich 42

以下是一行:

dataTable.Rows.OfType<DataRow>()
    .Select(dr => dr.Field<MyType>(columnName)).ToList();
Run Code Online (Sandbox Code Playgroud)

[ 编辑:System.Data.DataSetExtensions如果不能编译,请添加对项目的引用]

  • 这里的columnName值是多少? (22认同)

Ric*_* YS 28

List<MyType> listName = dataTableName.AsEnumerable().Select(m => new MyType()
{
   ID = m.Field<string>("ID"),
   Description = m.Field<string>("Description"),
   Balance = m.Field<double>("Balance"),
}).ToList()
Run Code Online (Sandbox Code Playgroud)


Kei*_*ith 18

DataTable有Linq扩展方法.

添加参考: System.Data.DataSetExtensions.dll

然后包括命名空间: using System.Data.DataSetExtensions

最后,您可以在DataSet和DataTables上使用Linq扩展:

var matches = myDataSet.Tables.First().Where(dr=>dr.Field<int>("id") == 1);
Run Code Online (Sandbox Code Playgroud)

在.Net 2.0上,您仍然可以添加泛型方法:

public static List<T> ConvertRowsToList<T>( DataTable input, Convert<DataRow, T> conversion) {
    List<T> retval = new List<T>()
    foreach(DataRow dr in input.Rows)
        retval.Add( conversion(dr) );

    return retval;
}
Run Code Online (Sandbox Code Playgroud)


小智 11

数据表到列表

    #region "getobject filled object with property reconized"

    public List<T> ConvertTo<T>(DataTable datatable) where T : new()
    {
        List<T> Temp = new List<T>();
        try
        {
            List<string> columnsNames = new List<string>();
            foreach (DataColumn DataColumn in datatable.Columns)
                columnsNames.Add(DataColumn.ColumnName);
            Temp = datatable.AsEnumerable().ToList().ConvertAll<T>(row => getObject<T>(row, columnsNames));
            return Temp;
        }
        catch
        {
            return Temp;
        }

    }
    public T getObject<T>(DataRow row, List<string> columnsName) where T : new()
    {
        T obj = new T();
        try
        {
            string columnname = "";
            string value = "";
            PropertyInfo[] Properties;
            Properties = typeof(T).GetProperties();
            foreach (PropertyInfo objProperty in Properties)
            {
                columnname = columnsName.Find(name => name.ToLower() == objProperty.Name.ToLower());
                if (!string.IsNullOrEmpty(columnname))
                {
                    value = row[columnname].ToString();
                    if (!string.IsNullOrEmpty(value))
                    {
                        if (Nullable.GetUnderlyingType(objProperty.PropertyType) != null)
                        {
                            value = row[columnname].ToString().Replace("$", "").Replace(",", "");
                            objProperty.SetValue(obj, Convert.ChangeType(value, Type.GetType(Nullable.GetUnderlyingType(objProperty.PropertyType).ToString())), null);
                        }
                        else
                        {
                            value = row[columnname].ToString().Replace("%", "");
                            objProperty.SetValue(obj, Convert.ChangeType(value, Type.GetType(objProperty.PropertyType.ToString())), null);
                        }
                    }
                }
            }
            return obj;
        }
        catch
        {
            return obj;
        }
    }

    #endregion
Run Code Online (Sandbox Code Playgroud)

IEnumerable集合到数据表

    #region "New DataTable"
    public DataTable ToDataTable<T>(IEnumerable<T> collection)
    {
        DataTable newDataTable = new DataTable();
        Type impliedType = typeof(T);
        PropertyInfo[] _propInfo = impliedType.GetProperties();
        foreach (PropertyInfo pi in _propInfo)
            newDataTable.Columns.Add(pi.Name, pi.PropertyType);

        foreach (T item in collection)
        {
            DataRow newDataRow = newDataTable.NewRow();
            newDataRow.BeginEdit();
            foreach (PropertyInfo pi in _propInfo)
                newDataRow[pi.Name] = pi.GetValue(item, null);
            newDataRow.EndEdit();
            newDataTable.Rows.Add(newDataRow);
        }
        return newDataTable;
    }
Run Code Online (Sandbox Code Playgroud)


小智 7

下面发布并使用反射的ConvertToList方法对我来说非常有效.谢谢.

我做了一些修改,使其适用于T属性类型的转换.

public List<T> ConvertToList<T>(DataTable dt)
{
    var columnNames = dt.Columns.Cast<DataColumn>()
            .Select(c => c.ColumnName)
            .ToList();
    var properties = typeof(T).GetProperties();
    return dt.AsEnumerable().Select(row =>
    {
        var objT = Activator.CreateInstance<T>();
        foreach (var pro in properties)
        {
            if (columnNames.Contains(pro.Name))
            {
                 PropertyInfo pI = objT.GetType().GetProperty(pro.Name);
                 pro.SetValue(objT, row[pro.Name] == DBNull.Value ? null : Convert.ChangeType(row[pro.Name], pI.PropertyType));
            }
        }
        return objT;
   }).ToList();
}
Run Code Online (Sandbox Code Playgroud)

希望能帮助到你.问候.


小智 7

那个漂亮的作品!

我对 @suneelsarraf 的答案进行了一些更新,并删除了它,Convert.ChangeType()因为它不断抛出Invalid Cast Exception. 看看吧!

#region *** Convert DT to List<Object> ***

    private List<I> ConvertTo<I>(DataTable datatable) where I : class
    {
        List<I> lstRecord = new List<I>();
        try
        {
            List<string> columnsNames = new List<string>();
            foreach (DataColumn DataColumn in datatable.Columns)
                columnsNames.Add(DataColumn.ColumnName);
            lstRecord = datatable.AsEnumerable().ToList().ConvertAll<I>(row => GetObject<I>(row, columnsNames));
            return lstRecord;
        }
        catch
        {
            return lstRecord;
        }

    }

    private I GetObject<I>(DataRow row, List<string> columnsName) where I : class
    {
        I obj = (I)Activator.CreateInstance(typeof(I));
        try
        {
            PropertyInfo[] Properties = typeof(I).GetProperties();
            foreach (PropertyInfo objProperty in Properties)
            {
                string columnname = columnsName.Find(name => name.ToLower() == objProperty.Name.ToLower());
                if (!string.IsNullOrEmpty(columnname))
                {
                    object dbValue = row[columnname];
                    if (dbValue != DBNull.Value)
                    {
                        if (Nullable.GetUnderlyingType(objProperty.PropertyType) != null)
                        {
                            objProperty.SetValue(obj, Convert.ChangeType(dbValue, Type.GetType(Nullable.GetUnderlyingType(objProperty.PropertyType).ToString())), null);
                        }
                        else
                        {
                            objProperty.SetValue(obj, Convert.ChangeType(dbValue, Type.GetType(objProperty.PropertyType.ToString())), null);
                        }
                    }
                }
            }
            return obj;
        }
        catch(Exception ex)
        {
            return obj;
        }
    }

    #endregion
Run Code Online (Sandbox Code Playgroud)

这就是您在代码中使用的方式。

// Other Codes Here
var lstResult = ConvertTo<TEntity>(dataTableName); // Convert DT to List<TEntity>
Run Code Online (Sandbox Code Playgroud)

玩得开心!2020 年请注意安全。


小智 7

我知道已经太晚了

但实际上在 Newtonsoft Json 的帮助下有一个简单的方法:

var json = JsonConvert.SerializeObject(dataTable);
var YourConvertedDataType = JsonConvert.DeserializeObject<YourDataType>(json);
Run Code Online (Sandbox Code Playgroud)


aba*_*hev 5

  1. IEnumerable<DataRow> rows = dataTable.AsEnumerable(); (System.Data.DataSetExtensions.dll)
  2. IEnumerable<DataRow> rows = dataTable.Rows.OfType<DataRow>(); (System.Core.dll)