如何将数据表转换为泛型类型列表。以下是场景。
我有名称为table1
的数据表,并包含col1,col2
列。 我们如何将此表转换为类型名称table1bj
的列表(对于每个数据表名称可以是不同的),其属性col1和col2具有兼容的数据类型,从数据表列数据类型开始。 < / p>
SO上有很多帖子,但这些帖子是将转换数据转换为预定义的对象列表。在我的情况下,我必须从数据表生成对象和动态列表。感谢。
答案 0 :(得分:4)
假设您已经使用两个属性table1bj
,col1
(相同)创建了类col2
(由于.NET命名约定而将其设为大写)。您只需使用Enumerable.Select
创建此类的实例,并使用ToList
创建通用List<table1bj>
:
List<table1bj> result = table1.AsEnumerable()
.Select(row => new table1bj
{
col1 = row.Field<string>("col1"),
col1 = row.Field<string>("col1")
}
).ToList();
我还假设这些属性为string
s,否则使用Field
扩展方法的正确类型。如果您不知道应该使用DataTable
的类型,因为它已经是具有动态类型的内存中集合。
答案 1 :(得分:1)
你可以这样做......
使用属性创建类:
public class table1bj
{
public string col1{ get; set; }
public string col2{ get; set; }
}
将DataTable转换为通用类型:
List<table1bj> Objtable1bj = table1.ToCollection<table1bj>();
答案 2 :(得分:1)
我很多时候都知道这个问题,但是我需要一个解决方案,在一种方法中将数据表转换为动态或泛型类型,我找不到答案,所以发表我的答案。
您可以使用扩展方法将数据表转换为如下所示的任何类型:
public static class Extension
{
public static IList<T> ToList<T>(this DataTable dt, bool isFirstRowColumnsHeader = false) where T : new()
{
var results = new List<T>();
if (dt != null && dt.Rows.Count > 0)
{
var columns = dt.Columns.Cast<DataColumn>().ToList();
var rows = dt.Rows.Cast<DataRow>().ToList();
var headerNames = columns.Select(col => col.ColumnName).ToList();
//
// Find properties name or columns name
if (isFirstRowColumnsHeader)
{
for (var i = 0; i < headerNames.Count; i++)
{
if (rows[0][i] != DBNull.Value && !string.IsNullOrEmpty(rows[0][i].ToString()))
headerNames[i] = rows[0][i].ToString();
}
//
// remove first row because that is header
rows.RemoveAt(0);
}
// Create dynamic or anonymous object for `T type
if (typeof(T) == typeof(System.Dynamic.ExpandoObject) ||
typeof(T) == typeof(System.Dynamic.DynamicObject) ||
typeof(T) == typeof(System.Object))
{
var dynamicDt = new List<dynamic>();
foreach (var row in rows)
{
dynamic dyn = new ExpandoObject();
dynamicDt.Add(dyn);
for (var i = 0; i < columns.Count; i++)
{
var dic = (IDictionary<string, object>)dyn;
dic[headerNames[i]] = row[columns[i]];
}
}
return (dynamic)dynamicDt;
}
else // other types of `T
{
var properties = typeof(T).GetProperties();
if (columns.Any() && properties.Any())
{
foreach (var row in rows)
{
var entity = new T();
for (var i = 0; i < columns.Count; i++)
{
if (!row.IsNull(columns[i]))
{
typeof(T).GetProperty(headerNames[i])? // ? -> maybe the property by name `headerNames[i]` is not exist in entity then get null!
.SetValue(entity, row[columns[i]] == DBNull.Value ? null : row[columns[i]]);
}
}
results.Add(entity);
}
}
}
}
return results;
}
}
答案 3 :(得分:0)
我们也可以通过Reflection来实现,这个方法有助于通过DataTable设置ClassObject属性:
using System.Reflection;
public void SetObjectProperties(object objClass, DataTable dataTable)
{
DataRow _dataRow = dataTable.Rows[0];
Type objType = objClass.GetType();
List<PropertyInfo> propertyList = new List<PropertyInfo>(objType.GetProperties());
foreach (DataColumn dc in _dataRow.Table.Columns)
{
var _prop = propertyList.Where(a => a.Name == dc.ColumnName).Select(a => a).FirstOrDefault();
if (_prop == null) continue;
_prop.SetValue(objClass, Convert.ChangeType(_dataRow[dc], Nullable.GetUnderlyingType(_prop.PropertyType) ?? _prop.PropertyType), null);
}
}