[英]Convert DataTable to List<T>
I have an strongly typed DataTable of type MyType
, I'd like convert it in a List<MyType>
.我有一个
MyType
类型的强类型 DataTable ,我想将它转换为List<MyType>
。
How can I do this ?我怎样才能做到这一点 ?
Thanks.谢谢。
The following does it in a single line:以下是在一行中完成的:
dataTable.Rows.OfType<DataRow>()
.Select(dr => dr.Field<MyType>(columnName)).ToList();
[ Edit : Add a reference to System.Data.DataSetExtensions
to your project if this does not compile] [编辑:如果这不能编译,则向您的项目添加对
System.Data.DataSetExtensions
的引用]
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()
There are Linq extension methods for DataTable. DataTable 有 Linq 扩展方法。
Add reference to: System.Data.DataSetExtensions.dll
添加对:
System.Data.DataSetExtensions.dll
引用
Then include the namespace: using System.Data.DataSetExtensions
然后包括命名空间:
using System.Data.DataSetExtensions
Finally you can use Linq extensions on DataSet and DataTables:最后,您可以在 DataSet 和 DataTables 上使用 Linq 扩展:
var matches = myDataSet.Tables.First().Where(dr=>dr.Field<int>("id") == 1);
On .Net 2.0 you can still add generic method:在 .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;
}
Data table to List要列出的数据表
#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
IEnumerable collection To Datatable 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;
}
The method ConvertToList that is posted below and uses reflection works perfectly for me.下面发布并使用反射的方法 ConvertToList 非常适合我。 Thanks.
谢谢。
I made a slight modification to make it work with conversions on the T property types.我做了一个小修改,使其适用于 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();
}
Hope it helps.希望能帮助到你。 Regards.
问候。
IEnumerable<DataRow> rows = dataTable.AsEnumerable();
(System.Data.DataSetExtensions.dll) IEnumerable<DataRow> rows = dataTable.Rows.OfType<DataRow>();
(System.Core.dll) That pretty works!!那个漂亮的作品!!
I made some updates from @suneelsarraf's answer and I removed Convert.ChangeType()
because it keeps throwing Invalid Cast Exception
.我从@suneelsarraf 的回答中做了一些更新,并删除了
Convert.ChangeType()
因为它不断抛出Invalid Cast Exception
。 Have a take a look!来看看吧!
#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
And this is how you use in your code.这就是您在代码中使用的方式。
// Other Codes Here
var lstResult = ConvertTo<TEntity>(dataTableName); // Convert DT to List<TEntity>
Have Fun!玩得开心! Be Safe in 2020.
2020年要安全。
Assuming your DataRow
s inherit from your own type, say MyDataRowType
, this should work:假设你的
DataRow
s从你自己的类型继承,比如MyDataRowType
,这应该有效:
List<MyDataRowType> list = new List<MyDataRowType>();
foreach(DataRow row in dataTable.Rows)
{
list.Add((MyDataRowType)row);
}
This is assuming, as you said in a comment, that you're using .NET 2.0 and don't have access to the LINQ extension methods.正如您在评论中所说,这是假设您使用的是 .NET 2.0 并且无权访问 LINQ 扩展方法。
Create a list with type <DataRow>
by extend the datatable
with AsEnumerable
call.创建类型的列表
<DataRow>
通过扩展datatable
与AsEnumerable
呼叫。
var mylist = dt.AsEnumerable().ToList();
Cheers!!干杯!! Happy Coding
快乐编码
please try this code:请试试这个代码:
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))
pro.SetValue(objT, row[pro.Name]);
}
return objT;
}).ToList();
}
试试这个代码,这是将数据表转换为列表的最简单方法
List<DataRow> listtablename = dataTablename.AsEnumerable().ToList();
There is a little example that you can use有一个小例子,你可以使用
DataTable dt = GetCustomersDataTable(null);
IEnumerable<SelectListItem> lstCustomer = dt.AsEnumerable().Select(x => new SelectListItem()
{
Value = x.Field<string>("CustomerId"),
Text = x.Field<string>("CustomerDescription")
}).ToList();
return lstCustomer;
thanks for all of posts.... I have done it with using Linq Query, to view this please visit the following link感谢所有帖子......我已经使用 Linq Query 完成了,要查看这个请访问以下链接
http://codenicely.blogspot.com/2012/02/converting-your-datatable-into-list.html http://codenicely.blogspot.com/2012/02/converting-your-datatable-into-list.html
you can convert your datatable to list.您可以将数据表转换为列表。 check the following link
检查以下链接
https://stackoverflow.com/a/35171050/1805776 https://stackoverflow.com/a/35171050/1805776
public static class Helper
{
public static List<T> DataTableToList<T>(this DataTable dataTable) where T : new()
{
var dataList = new List<T>();
//Define what attributes to be read from the class
const System.Reflection.BindingFlags flags = System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance;
//Read Attribute Names and Types
var objFieldNames = typeof(T).GetProperties(flags).Cast<System.Reflection.PropertyInfo>().
Select(item => new
{
Name = item.Name,
Type = Nullable.GetUnderlyingType(item.PropertyType) ?? item.PropertyType
}).ToList();
//Read Datatable column names and types
var dtlFieldNames = dataTable.Columns.Cast<DataColumn>().
Select(item => new
{
Name = item.ColumnName,
Type = item.DataType
}).ToList();
foreach (DataRow dataRow in dataTable.AsEnumerable().ToList())
{
var classObj = new T();
foreach (var dtField in dtlFieldNames)
{
System.Reflection.PropertyInfo propertyInfos = classObj.GetType().GetProperty(dtField.Name);
var field = objFieldNames.Find(x => x.Name == dtField.Name);
if (field != null)
{
if (propertyInfos.PropertyType == typeof(DateTime))
{
propertyInfos.SetValue
(classObj, convertToDateTime(dataRow[dtField.Name]), null);
}
else if (propertyInfos.PropertyType == typeof(Nullable<DateTime>))
{
propertyInfos.SetValue
(classObj, convertToDateTime(dataRow[dtField.Name]), null);
}
else if (propertyInfos.PropertyType == typeof(int))
{
propertyInfos.SetValue
(classObj, ConvertToInt(dataRow[dtField.Name]), null);
}
else if (propertyInfos.PropertyType == typeof(long))
{
propertyInfos.SetValue
(classObj, ConvertToLong(dataRow[dtField.Name]), null);
}
else if (propertyInfos.PropertyType == typeof(decimal))
{
propertyInfos.SetValue
(classObj, ConvertToDecimal(dataRow[dtField.Name]), null);
}
else if (propertyInfos.PropertyType == typeof(String))
{
if (dataRow[dtField.Name].GetType() == typeof(DateTime))
{
propertyInfos.SetValue
(classObj, ConvertToDateString(dataRow[dtField.Name]), null);
}
else
{
propertyInfos.SetValue
(classObj, ConvertToString(dataRow[dtField.Name]), null);
}
}
else
{
propertyInfos.SetValue
(classObj, Convert.ChangeType(dataRow[dtField.Name], propertyInfos.PropertyType), null);
}
}
}
dataList.Add(classObj);
}
return dataList;
}
private static string ConvertToDateString(object date)
{
if (date == null)
return string.Empty;
return date == null ? string.Empty : Convert.ToDateTime(date).ConvertDate();
}
private static string ConvertToString(object value)
{
return Convert.ToString(ReturnEmptyIfNull(value));
}
private static int ConvertToInt(object value)
{
return Convert.ToInt32(ReturnZeroIfNull(value));
}
private static long ConvertToLong(object value)
{
return Convert.ToInt64(ReturnZeroIfNull(value));
}
private static decimal ConvertToDecimal(object value)
{
return Convert.ToDecimal(ReturnZeroIfNull(value));
}
private static DateTime convertToDateTime(object date)
{
return Convert.ToDateTime(ReturnDateTimeMinIfNull(date));
}
public static string ConvertDate(this DateTime datetTime, bool excludeHoursAndMinutes = false)
{
if (datetTime != DateTime.MinValue)
{
if (excludeHoursAndMinutes)
return datetTime.ToString("yyyy-MM-dd");
return datetTime.ToString("yyyy-MM-dd HH:mm:ss.fff");
}
return null;
}
public static object ReturnEmptyIfNull(this object value)
{
if (value == DBNull.Value)
return string.Empty;
if (value == null)
return string.Empty;
return value;
}
public static object ReturnZeroIfNull(this object value)
{
if (value == DBNull.Value)
return 0;
if (value == null)
return 0;
return value;
}
public static object ReturnDateTimeMinIfNull(this object value)
{
if (value == DBNull.Value)
return DateTime.MinValue;
if (value == null)
return DateTime.MinValue;
return value;
}
}
I know it a too late我知道为时已晚
but actually there is a simple way with help of Newtonsoft Json:但实际上在 Newtonsoft Json 的帮助下有一个简单的方法:
var json = JsonConvert.SerializeObject(dataTable);
var YourConvertedDataType = JsonConvert.DeserializeObject<YourDataType>(json);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.