DataTable 转实体
发表于:2026-10-31 作者:千家信息网编辑
千家信息网最后更新 2026年10月31日,因为Linq的查询功能很强大,所以从数据库中拿到的数据为了处理方便,我都会转换成实体集合List。开始用的是硬编码的方式,好理解,但通用性极低,下面是控件台中的代码: 1 using System;
千家信息网最后更新 2026年10月31日DataTable 转实体
因为Linq的查询功能很强大,所以从数据库中拿到的数据为了处理方便,我都会转换成实体集合List
开始用的是硬编码的方式,好理解,但通用性极低,下面是控件台中的代码:
1 using System; 2 using System.Collections.Generic; 3 using System.Data; 4 using System.Linq; 5 using System.Text; 6 using System.Threading.Tasks; 7 8 namespace Demo1 9 {10 class Program11 {12 static void Main(string[] args)13 {14 DataTable dt = Query();15 List usrs = new List(dt.Rows.Count);16 //硬编码,效率比较高,但灵活性不够,如果实体改变了,都需要修改代码17 foreach (DataRow dr in dt.Rows)18 {19 Usr usr = new Usr { ID = dr.Field("ID"), Name = dr.Field("Name") };20 usrs.Add(usr);21 }22 usrs.Clear();23 }24 25 /// 26 /// 查询数据27 /// 28 /// 29 private static DataTable Query()30 {31 DataTable dt = new DataTable();32 dt.Columns.Add("ID", typeof(Int32));33 dt.Columns.Add("Name", typeof(String));34 for (int i = 0; i < 1000000; i++)35 {36 dt.Rows.Add(new Object[] { i, Guid.NewGuid().ToString() });37 }38 return dt;39 }40 }41 class Usr42 {43 public Int32? ID { get; set; }44 public String Name { get; set; }45 }46 } 后来用反射来做这,对实体的属性用反射去赋值,这样就可以对所有的实体通用,且增加属性后不用修改代码。
程序如下:
1 static class EntityConvert 2 { 3 /// 4 /// DataTable转为List 5 /// 6 /// 7 /// 8 /// 9 public static List ToList(this DataTable dt) where T : class, new()10 {11 List colletion = new List();12 PropertyInfo[] pInfos = typeof(T).GetProperties();13 foreach (DataRow dr in dt.Rows)14 {15 T t = new T();16 foreach (PropertyInfo pInfo in pInfos)17 {18 if (!pInfo.CanWrite) continue;19 pInfo.SetValue(t, dr[pInfo.Name]);20 }21 colletion.Add(t);22 }23 return colletion;24 }25 } 增加一个扩展方法,程序更加通用。但效率不怎么样,100万行数据【只有两列】,转换需要2秒
后来想到用委托去做 委托原型如下
1 Funcfunc = dr => new Usr { ID = dr.Field ("ID"), Name = dr.Field ("Name") };
代码如下:
1 static void Main(string[] args) 2 { 3 DataTable dt = Query(); 4 Func func = dr => new Usr { ID = dr.Field("ID"), Name = dr.Field("Name") }; 5 List usrs = new List(dt.Rows.Count); 6 Stopwatch sw = Stopwatch.StartNew(); 7 foreach (DataRow dr in dt.Rows) 8 { 9 Usr usr = func(dr);10 usrs.Add(usr);11 }12 sw.Stop();13 Console.WriteLine(sw.ElapsedMilliseconds);14 usrs.Clear();15 Console.ReadKey();16 } 速度确实快了很多,我电脑测试了一下,需要 0.4秒。但问题又来了,这个只能用于Usr这个类,得想办法把这个类抽象成泛型T,既有委托的高效,又有
泛型的通用。
问题就在动态地产生上面的委托了,经过一下午的折腾终于折腾出来了动态产生委托的方法。主要用到了动态Lambda表达式
1 public static class EntityConverter 2 { 3 /// 4 /// DataTable生成实体 5 /// 6 /// 7 /// 8 /// 9 public static List ToList(this DataTable dataTable) where T : class, new()10 {11 if (dataTable == null || dataTable.Rows.Count <= 0) throw new ArgumentNullException("dataTable", "当前对象为null无法生成表达式树");12 Func func = dataTable.Rows[0].ToExpression();13 List collection = new List(dataTable.Rows.Count);14 foreach (DataRow dr in dataTable.Rows)15 {16 collection.Add(func(dr));17 }18 return collection;19 }20 21 /// 22 /// 生成表达式23 /// 24 /// 25 /// 26 /// 27 public static Func ToExpression(this DataRow dataRow) where T : class, new()28 {29 if (dataRow == null) throw new ArgumentNullException("dataRow", "当前对象为null 无法转换成实体");30 ParameterExpression paramter = Expression.Parameter(typeof(DataRow), "dr");31 List binds = new List();32 for (int i = 0; i < dataRow.ItemArray.Length; i++)33 {34 String colName = dataRow.Table.Columns[i].ColumnName;35 PropertyInfo pInfo = typeof(T).GetProperty(colName);36 if (pInfo == null) continue;37 MethodInfo mInfo = typeof(DataRowExtensions).GetMethod("Field", new Type[] { typeof(DataRow), typeof(String) }).MakeGenericMethod(pInfo.PropertyType);38 MethodCallExpression call = Expression.Call(mInfo, paramter, Expression.Constant(colName, typeof(String)));39 MemberAssignment bind = Expression.Bind(pInfo, call);40 binds.Add(bind);41 }42 MemberInitExpression init = Expression.MemberInit(Expression.New(typeof(T)), binds.ToArray());43 return Expression.Lambda>(init, paramter).Compile();44 }45 } 经过测试,用这个方法在同样的条件下转换实体需要 0.47秒。除了第一次用反射生成Lambda表达式外,后续的转换直接用的表达式。
实体
表达式
委托
代码
数据
生成
动态
方法
反射
对象
属性
效率
程序
编码
问题
查询
测试
强大
不怎么样
不够
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
科技互联网技术
广州宏创互联网科技
菲比寻常互联网科技
广西互联网科技公司
卓越科技互联网 招聘
互联网科技创新企业排名
花神(南京)互联网科技有限公司
哈尔滨屹滨互联网科技有限公司
迪庆互联网科技招生
爱医互联网络科技
互联网科技圈年度人物
智帮互联网科技公司最近动向
杭州披云加互联网科技有限公司
互联网科技年终奖
互联网安防科技感
风投北京互联网科技
互联网科技包装股
马化腾互联网科技教学
玉溪新华互联网科技怎么选
绵阳真晨互联网科技有限公司
科技类互联网
北京互联网科技
唐信互联网科技
哈尔滨新华互联网科技学院
中国互联网有什么科技含量
乌苏新华互联网科技做什么的
互联网科技创新的路径
四川互联网展示科技馆设计
宁波跨境商互联网科技有限公司
颐高云石互联网科技