C# 将datatable转换为泛型类型的列表
如何将datatable转换为泛型类型的列表。下面是场景。 我有一个名为C# 将datatable转换为泛型类型的列表,c#,.net,linq,datatable,C#,.net,Linq,Datatable,如何将datatable转换为泛型类型的列表。下面是场景。 我有一个名为table1的数据表,它包含col1、col2列如何将此表转换为类型名称列表table1bj(每个数据表名称可能不同),属性为col1和col2,数据类型与datatable列数据类型兼容。 有很多关于SO的帖子,但这些都是通过将datatable转换为预定义的对象列表实现的。在我的例子中,我必须从数据表生成对象并动态列出。谢谢。假设您已经创建了具有两个属性的类table1bj(由于.NET命名约定,请考虑将其设置为大写)c
table1
的数据表,它包含col1、col2
列如何将此表转换为类型名称列表table1bj
(每个数据表名称可能不同),属性为col1和col2,数据类型与datatable列数据类型兼容。
有很多关于SO的帖子,但这些都是通过将datatable转换为预定义的对象列表实现的。在我的例子中,我必须从数据表生成对象并动态列出。谢谢。假设您已经创建了具有两个属性的类
table1bj
(由于.NET命名约定,请考虑将其设置为大写)col1
,col2
(相同)。您只需使用可枚举。选择可创建此类的实例,选择可列出可创建通用列表
:
List result=table1.AsEnumerable()
.选择(行=>new table1bj
{
col1=行字段(“col1”),
col1=行字段(“col1”)
}
).ToList();
我还假设这些属性是string
s,否则请在字段
扩展方法中使用正确的类型。如果您不知道类型,您应该使用DataTable
,因为它已经是一个具有动态类型的内存集合 你可以这样做
使用属性创建类:
public class table1bj
{
public string col1{ get; set; }
public string col2{ get; set; }
}
List<table1bj> Objtable1bj = table1.ToCollection<table1bj>();
将数据表转换为泛型类型:
public class table1bj
{
public string col1{ get; set; }
public string col2{ get; set; }
}
List<table1bj> Objtable1bj = table1.ToCollection<table1bj>();
List Objtable1bj=table1.ToCollection();
我们也可以通过反射来实现,此方法有助于通过DataTable设置类对象属性:
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);
}
}
使用系统反射;
公共void SetObjectProperties(对象对象对象类,数据表DataTable)
{
DataRow_DataRow=dataTable.Rows[0];
类型objType=objClass.GetType();
List propertyList=新列表(objType.GetProperties());
foreach(dataRow.Table.Columns中的DataColumn dc)
{
var\u prop=propertyList.Where(a=>a.Name==dc.ColumnName).Select(a=>a.FirstOrDefault();
如果(_prop==null)继续;
_prop.SetValue(对象类,Convert.ChangeType(_dataRow[dc],null.getUnderlineType(_prop.PropertyType)??_prop.PropertyType),null);
}
}
我知道这个问题以前问过很多次,但我也需要一个解决方案,用一个方法将数据表转换为动态或泛型类型,我找不到答案,所以请发布我的答案
您可以使用扩展方法将数据表转换为以下任何类型:
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;
}
}
公共静态类扩展
{
公共静态IList ToList(此数据表dt,bool isFirstRowColumnsHeader=false),其中T:new()
{
var results=新列表();
如果(dt!=null&&dt.Rows.Count>0)
{
var columns=dt.columns.Cast().ToList();
var rows=dt.rows.Cast().ToList();
var headerNames=columns.Select(col=>col.ColumnName.ToList();
//
//查找属性名称或列名称
如果(isFirstRowColumnsHeader)
{
对于(变量i=0;i可能名为`headerNames[i]`的属性在实体中不存在,然后获取null!
.SetValue(实体,行[columns[i]]==DBNull.Value?null:行[columns[i]]);
}
}
结果:增加(实体);
}
}
}
}
返回结果;
}
}
为什么不使用实体框架?能否告诉我们如何填充数据表?用户输入?绑定到集合?@DaveRook:我们正在使用wcf服务进行数据访问layer@erajWCF数据服务和EF可以很好地结合在一起。@提姆的回答是正确的,这里只需注意的是,直接从数据库中获取<代码> Table 1BJ < /代码>。不填充中间数据表,您是否可以引用收集方法描述?它是一个扩展方法。@Sangram:但它不是框架的一部分,所以您应该