实体类和DataTable的转换
引子
最近在项目中在数据库查询的时间,总是要用到数据表到实体类对象列表的转化,自己封装了一个转换的方法,用起来还比较方便,记下来,以后可以重复使用,原理就主要是利用反射,当然有更好的ORM框架可以实现,主要的原因就是我这里没有用orm。
实现
话不多少,直接上实现代码
/// <summary> /// 数据表转换类 /// </summary> /// <typeparam name="T"></typeparam> public class DbTableConvertor<T> where T : new() { /// <summary> /// 将DataTable转换为实体列表 /// 作者: oldman /// 创建时间: 2015年9月13日 /// </summary> /// <param name="dt">待转换的DataTable</param> /// <returns></returns> public List<T> ConvertToList(DataTable dt) { // 定义集合 var list = new List<T>(); if (0 == dt.Rows.Count) { return list; } //遍历DataTable中所有的数据行 foreach (DataRow dr in dt.Rows) { var entity = new T(); // 获得此模型的公共属性 var propertys = entity.GetType().GetProperties(); //遍历该对象的所有属性 foreach (var p in propertys) { //将属性名称赋值给临时变量 string tmpName = p.Name; //检查DataTable是否包含此列(列名==对象的属性名) if (dt.Columns.Contains(tmpName)) { // 判断此属性是否有Setter if (!p.CanWrite) { continue; //该属性不可写,直接跳出 } //取值 var value = dr[tmpName]; //如果非空,则赋给对象的属性 if (value != DBNull.Value) { p.SetValue(entity, value, null); } } } //对象添加到泛型集合中 list.Add(entity); } return list; } /// <summary> /// 将DataTable的首行转换为实体 /// 作者: oldman /// 创建时间: 2015年9月13日 /// </summary> /// <param name="dt">待转换的DataTable</param> /// <returns></returns> public T ConvertToEntity(DataTable dt) { var entity = new T(); if (0 == dt.Rows.Count) { return entity; } // 获得此模型的公共属性 var propertys = entity.GetType().GetProperties(); //遍历该对象的所有属性 foreach (var p in propertys) { //将属性名称赋值给临时变量 string tmpName = p.Name; //检查DataTable是否包含此列(列名==对象的属性名) if (dt.Columns.Contains(tmpName)) { // 判断此属性是否有Setter if (!p.CanWrite) { continue; //该属性不可写,直接跳出 } //取值 var value = dt.Rows[0][tmpName]; //如果非空,则赋给对象的属性 if (value != DBNull.Value) { p.SetValue(entity, value, null); } } } return entity; } }
更改
在几位院子里大神的指点下,做了一些修改,以后应该多注意这些细节,感谢@双鱼座和@梦在旅途,修改后的如下
using System; using System.Collections.Generic; using System.Data; using System.Linq; using System.Reflection; namespace SolrNetDemo { /// <summary> /// 数据表转换类 /// </summary> /// <typeparam name="T"></typeparam> public class DbTableConvertor<T> where T : new() { /// <summary> /// 将DataTable转换为实体列表 /// 作者: oldman /// 创建时间: 2015年9月13日 /// </summary> /// <param name="dt">待转换的DataTable</param> /// <returns></returns> public List<T> ConvertToList(DataTable dt) { // 定义集合 var list = new List<T>(); if (0 == dt.Rows.Count) { return list; } // 获得此模型的可写公共属性 IEnumerable<PropertyInfo> propertys = new T().GetType().GetProperties().Where(u => u.CanWrite); list = ConvertToEntity(dt, propertys); return list; } /// <summary> /// 将DataTable的首行转换为实体 /// 作者: oldman /// 创建时间: 2015年9月13日 /// </summary> /// <param name="dt">待转换的DataTable</param> /// <returns></returns> public T ConvertToEntity(DataTable dt) { DataTable dtTable = dt.Clone(); dtTable.Rows.Add(dt.Rows[0].ItemArray); return ConvertToList(dtTable)[0]; } private List<T> ConvertToEntity(DataTable dt, IEnumerable<PropertyInfo> propertys) { var list = new List<T>(); //遍历DataTable中所有的数据行 foreach (DataRow dr in dt.Rows) { var entity = new T(); //遍历该对象的所有属性 foreach (PropertyInfo p in propertys) { //将属性名称赋值给临时变量 string tmpName = p.Name; //检查DataTable是否包含此列(列名==对象的属性名) if (!dt.Columns.Contains(tmpName)) continue; //取值 object value = dr[tmpName]; //如果非空,则赋给对象的属性 if (value != DBNull.Value) { p.SetValue(entity, value, null); } } //对象添加到泛型集合中 list.Add(entity); } return list; } } }
确实看清了进步的空间,希望大家多交流,共同进步。
注释的都很清楚,欢迎拍砖。
本人的.NET学习技术交流群:226704167
努力学习,只为一个梦想。
分类:
C#基础
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!