.NET把DataTable转换为List〈Model〉的形式

本文介绍了一种将DataTable转换为List<Model>的方法,通过泛型和反射技术实现了灵活的数据转换,适用于.NET应用程序的数据处理场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在循环一个DataTable的时候,还要指定列名,的确有些不方便,今日想能不能转换为类似List<Model>的形式呢,这样操作会方便的多。主要代码为类ModelConvertHelper,主要思路是利用泛型传入实体类Model,DataTable的每一行都是一个实体,所以首先要循环DataTable,定义此泛型的对象T t = new T(),然后利用反射获得实体类里面的公共属性,具体代码如下的PropertyInfo[] propertys = t.GetType().GetProperties();的部分,然后利用如下循环:

foreach (PropertyInfo pi in propertys)
{
tempName = pi.Name;
// 检查DataTable是否包含此列
if (dt.Columns.Contains(tempName))
{
// 判断此属性是否有Setter
if (!pi.CanWrite)
continue;
object value = dr[tempName];
if (value != DBNull.Value)
pi.SetValue(t, value, null);
}
}

判断如果传入的DataTable和实体类的字段一致的话,就把此值赋给上面新定义的泛型对象t。最后ts.Add(t);把此t加入集合

完整代码及使用方式如下:

using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; //需要导入的命名空间 using System.Data; using System.Reflection; using System.Globalization; namespace WebApplModelConvert { public partial class _Default : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { //使用方式,获得DataTable DataTable dt = DataBusiness.GetDataSet().Tables[0]; //进行转化 IList < Student > list= ModelConvertHelper<Student>.ConvertToModel(dt); //循环输出 foreach (Student stu in list) { Response.Write("学号:" + stu.StuNo + ",姓名:" + stu.StuName+",年龄:" + stu.StuAge.ToString()); } } } /// <summary> /// 逻辑层数据库操作,正常情况此处的数据来自数据库 /// </summary> public static class DataBusiness { //返回DataSet public static DataSet GetDataSet() { DataSet ds = new DataSet(); DataTable dt = new DataTable(); dt.Columns.Add("StuNo", Type.GetType("System.String")); dt.Columns.Add("StuName", Type.GetType("System.String")); dt.Columns.Add("StuAge", Type.GetType("System.Int32")); DataRow dr = dt.NewRow(); dr["StuNo"] = "001"; dr["StuName"] = "张三"; dr["StuAge"] = 22; dt.Rows.Add(dr); dr = dt.NewRow(); dr["StuNo"] = "002"; dr["StuName"] = "李四"; dr["StuAge"] = 33; dt.Rows.Add(dr); ds.Tables.Add(dt); return ds; } } /// <summary> /// 定义一个实体类 /// </summary> public class Student { public string StuNo { get; set; } public string StuName { get; set; } public int? StuAge { get; set; } } /// <summary> /// 把DataTable转换为List<Model>形式 /// </summary> public class ModelConvertHelper<T> where T : new() //where T : new()代表作为泛型的类型T,必须是具有公共的无参数构造函数 { public static IList<T> ConvertToModel(DataTable dt) { // 定义集合 IList<T> ts = new List<T>(); // 获得此模型的类型 Type type = typeof(T); string tempName = ""; foreach (DataRow dr in dt.Rows) { T t = new T(); // 获得此模型的公共属性 PropertyInfo[] propertys = t.GetType().GetProperties(); foreach (PropertyInfo pi in propertys) { tempName = pi.Name; // 检查DataTable是否包含此列 if (dt.Columns.Contains(tempName)) { // 判断此属性是否有Setter if (!pi.CanWrite) continue; object value = dr[tempName]; if (value != DBNull.Value) { //pi.SetValue(t, value, null); pi.SetValue(t, Convert.ChangeType(value, pi.PropertyType, CultureInfo.CurrentCulture), null); } } } ts.Add(t); } return ts; } } }

运行结果:

学号:001,姓名:张三学号:002,姓名:李四


注意:
1、在上面的代码中,
pi.SetValue(t, value, null);最好写成以下形式:
pi.SetValue(t, Convert.ChangeType(value, pi.PropertyType, CultureInfo.CurrentCulture), null);
2、数字不能为泛型,否则出现以下错误
类型“System.String”的对象无法转换为类型“System.Nullable`1[System.Int32]”。
当然这里是可以,原因是在增加列的同时指定了数据类型,如下代码,如果不指定数据类型就会出现错误
dt.Columns.Add("StuAge", Type.GetType("System.Int32"));
但是我们在实际开发的时候,一般是系统默认指定,而没有指定列类型。所以最好在你的Model层把数字为泛型的地方都取消,如上面的public int? StuAge { get; set; } 最好写为public int StuAge { get; set; }

参考:http://www.xueit.com/html/2009-09/21_4465_00.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值