C# 将数据表转换为列表<;T>;
有没有一种方法可以在不指定单个字段的情况下将数据表从C# 将数据表转换为列表<;T>;,c#,C#,有没有一种方法可以在不指定单个字段的情况下将数据表从转换为列表?更简洁?推断属性 public class Task { public int Id { get; set; } public string Name { get; set; } } public class TasksDAL { public static List<Task> GetTasks() { DataTable dt = GetTasksDT();
转换为列表
?更简洁?推断属性
public class Task
{
public int Id { get; set; }
public string Name { get; set; }
}
public class TasksDAL
{
public static List<Task> GetTasks()
{
DataTable dt = GetTasksDT();
List<Task> tasks = new List<Task>();
tasks = (from DataRow row in dt.Rows
select new Task
{
Id = (int)row["Id"],
Name = row["Name"].ToString()
}).ToList();
return tasks;
}
}
公共类任务
{
公共int Id{get;set;}
公共字符串名称{get;set;}
}
公共类任务
{
公共静态列表GetTasks()
{
DataTable dt=GetTasksDT();
列表任务=新列表();
tasks=(来自dt.Rows中的DataRow行
选择新任务
{
Id=(int)行[“Id”],
名称=行[“名称”]。ToString()
}).ToList();
返回任务;
}
}
我有一段旧代码,它使用反射从数据表填充obj列表
列的名称必须与属性的名称相同
var result = dt.ToList<Task>()
public static List<T> ToList<T>(this DataTable dt) where T : new()
{
var returnList = new List<T>();
var properties = new PropertyInfo[dt.Columns.Count];
for (int i = 0; i < properties.Length; i++)
{
properties[i] = typeof(T).GetProperty(dt.Columns[i].Caption, BindingFlags.Public | BindingFlags.Instance | BindingFlags.IgnoreCase);
}
PropertyInfo property;
foreach (DataRow dr in dt.Rows)
{
T resultItem = new T();
for (int i = 0; i < properties.Length; i++)
{
if ((property = properties[i]) == null)
{
continue;
}
if (!DBNull.Value.Equals((object)dr[i] ?? (object)DBNull.Value))
{
property.SetValue(resultItem, dr[i], null);
}
}
returnList.Add(resultItem);
}
return returnList;
}
var result=dt.ToList()
公共静态列表ToList(此数据表dt),其中T:new()
{
var returnList=新列表();
var properties=newpropertyinfo[dt.Columns.Count];
for(int i=0;i
我更喜欢将IEnumerable
返回到列表
并以相反的方向反映,为所有属性和字段分配匹配的列名:
使用MemberInfo
上的一些扩展来处理属性或字段:
public static object GetValue(this MemberInfo member, object srcObject) {
if (member.MemberType == MemberTypes.Property)
return ((PropertyInfo)member).GetValue(srcObject, null);
else if (member.MemberType == MemberTypes.Field)
return ((FieldInfo)member).GetValue(srcObject);
else
throw new Exception("Property must be of type FieldInfo or PropertyInfo");
}
public static void SetValue<T>(this MemberInfo member, object destObject, T value) {
if (member.MemberType == MemberTypes.Property)
((PropertyInfo)member).SetValue(destObject, value);
else if (member.MemberType == MemberTypes.Field)
((FieldInfo)member).SetValue(destObject, value);
else
throw new Exception("Property must be of type FieldInfo or PropertyInfo");
}
public static Type GetMemberType(this MemberInfo member) {
switch (member.MemberType) {
case MemberTypes.Field:
return ((FieldInfo)member).FieldType;
case MemberTypes.Property:
return ((PropertyInfo)member).PropertyType;
case MemberTypes.Event:
return ((EventInfo)member).EventHandlerType;
default:
throw new ArgumentException("MemberInfo must be if type FieldInfo, PropertyInfo or EventInfo", "member");
}
}
公共静态对象GetValue(此MemberInfo成员,对象srcObject){
if(member.MemberType==MemberTypes.Property)
return((PropertyInfo)成员).GetValue(srcObject,null);
else if(member.MemberType==MemberTypes.Field)
return((FieldInfo)成员).GetValue(srcObject);
其他的
抛出新异常(“属性必须为FieldInfo或PropertyInfo类型”);
}
公共静态void SetValue(此MemberInfo成员、对象destObject、T值){
if(member.MemberType==MemberTypes.Property)
((PropertyInfo)成员).SetValue(destObject,value);
else if(member.MemberType==MemberTypes.Field)
((FieldInfo)成员).SetValue(destObject,value);
其他的
抛出新异常(“属性必须为FieldInfo或PropertyInfo类型”);
}
公共静态类型GetMemberType(此MemberInfo成员){
开关(成员.成员类型){
案例成员类型。字段:
返回((FieldInfo)成员)。字段类型;
案例成员类型。属性:
返回((PropertyInfo)成员);
案例成员类型。事件:
return((EventInfo)成员).EventHandlerType;
违约:
抛出新ArgumentException(“如果类型为FieldInfo、PropertyInfo或EventInfo,则MemberInfo必须为”“member”);
}
}
您可以获取包含列的成员列表并分配它们:
public static IEnumerable<T> ToEnumerable<T>(this DataTable dt) where T : new() {
var props = typeof(T).GetMembers(BindingFlags.Public|BindingFlags.Instance)
.Where(p => dt.Columns.Contains(p.Name) && (p.MemberType == MemberTypes.Field || p.MemberType == MemberTypes.Property)).ToList();
foreach (var row in dt.AsEnumerable()) {
var aT = new T();
foreach (var p in props)
p.SetValue(aT, row[p.Name]);
yield return aT;
}
}
公共静态IEnumerable到numerable(此数据表dt),其中T:new(){
var props=typeof(T).GetMembers(BindingFlags.Public | BindingFlags.Instance)
.Where(p=>dt.Columns.Contains(p.Name)和&(p.MemberType==MemberTypes.Field | | p.MemberType==MemberTypes.Property)).ToList();
foreach(dt.AsEnumerable()中的变量行){
var aT=新的T();
foreach(道具中的var p)
p、 设置值(在第行[p.Name]);
收益率;
}
}
我想这会有帮助。我相信你应该创建地图IDataReader,List。这可能对您有所帮助您可以为Task
创建一个构造函数,该构造函数将DataRow
作为其参数。您的代码有点冗余-没有理由创建一个新列表
,然后立即丢弃它,只需使用var tasks=
并去掉前一行即可。但是,对于包含更多字段的通用解决方案,您需要进行反射。您确定首先需要DataTable
?为什么不更改数据层,使其返回一个列表
?我正在返回一个列表。您是说我不需要使用ADO.NET从数据库检索数据吗?请怀疑这是否适用于var-除非您直接指定类型。@user6144226谢谢,因为它不在代码中,任务类型已被删除。