自用的基于Emit的C#下DataTable转实体类方法
来源:互联网 发布:淘宝哪些店铺布料便宜 编辑:程序博客网 时间:2024/05/24 06:06
自用的基于Emit的C#下DataTable转实体类方法
之前一直在做WebForm的开发,数据绑定时直接DataTable绑定Gridview很方便,但是最近开始往MVC转,数据列表的传递和页面展示基本上是以List为主,像下面这样,遍历实体类的各个字段去赋值的办法当然是最浪费时间的。
if (row["ID"] != null && row["ID"].ToString() != "") { model.bedID = int.Parse(row["ID"].ToString()); }
通过在网上查资料和一定的比较,我选择了以下基于Emit的DataTable转实体类的方法。
按照下边的代码新建一个类EntityConverter
:
public static class EntityConverter { public static List<T> ToList<T>(this DataTable dt) where T : class, new() { List<T> list = new List<T>(); if (dt == null || dt.Rows.Count == 0) return list; DataTableEntityBuilder<T> eblist = DataTableEntityBuilder<T>.CreateBuilder(dt.Rows[0]); foreach (DataRow info in dt.Rows) list.Add(eblist.Build(info)); dt.Dispose(); dt = null; return list; } public class DataTableEntityBuilder<Entity> { private static readonly MethodInfo getValueMethod = typeof(DataRow).GetMethod("get_Item", new Type[] { typeof(int) }); private static readonly MethodInfo isDBNullMethod = typeof(DataRow).GetMethod("IsNull", new Type[] { typeof(int) }); private delegate Entity Load(DataRow dataRecord); private Load handler; private DataTableEntityBuilder() { } public Entity Build(DataRow dataRecord) { return handler(dataRecord); } public static DataTableEntityBuilder<Entity> CreateBuilder(DataRow dataRecord) { DataTableEntityBuilder<Entity> dynamicBuilder = new DataTableEntityBuilder<Entity>(); DynamicMethod method = new DynamicMethod("DynamicCreateEntity", typeof(Entity), new Type[] { typeof(DataRow) }, typeof(Entity), true); ILGenerator generator = method.GetILGenerator(); LocalBuilder result = generator.DeclareLocal(typeof(Entity)); generator.Emit(OpCodes.Newobj, typeof(Entity).GetConstructor(Type.EmptyTypes)); generator.Emit(OpCodes.Stloc, result); for (int i = 0; i < dataRecord.ItemArray.Length; i++) { PropertyInfo propertyInfo = typeof(Entity).GetProperty(dataRecord.Table.Columns[i].ColumnName); Label endIfLabel = generator.DefineLabel(); if (propertyInfo != null && propertyInfo.GetSetMethod() != null) { generator.Emit(OpCodes.Ldarg_0); generator.Emit(OpCodes.Ldc_I4, i); generator.Emit(OpCodes.Callvirt, isDBNullMethod); generator.Emit(OpCodes.Brtrue, endIfLabel); generator.Emit(OpCodes.Ldloc, result); generator.Emit(OpCodes.Ldarg_0); generator.Emit(OpCodes.Ldc_I4, i); generator.Emit(OpCodes.Callvirt, getValueMethod); generator.Emit(OpCodes.Unbox_Any, propertyInfo.PropertyType); generator.Emit(OpCodes.Callvirt, propertyInfo.GetSetMethod()); generator.MarkLabel(endIfLabel); } } generator.Emit(OpCodes.Ldloc, result); generator.Emit(OpCodes.Ret); dynamicBuilder.handler = (Load)method.CreateDelegate(typeof(Load)); return dynamicBuilder; } } }
在DbHelperSQL里面再简单封装一下:
public static List<T> Query<T>(string sql) where T : class, new() { DataTable dt = DbHelperSQL.Query(sql).Tables[0]; if (dt != null && dt.Rows.Count > 0) { return EntityConverter.ToList<T>(dt); } else { return null; } }
使用的时候:
string sql="select top 10 * from user"; List<Model.User> listUser=DbHelperSQL.Query<Model.User>(sql);
注意:
- 1、定义的Model的各个属性的名称要和Select语句执行结果的列名一致
- 2、定义的Model的各个属性的数据类型要和数据库定义的一致
- 3、关于数据列与属性对应:Model中的属性SQL里面可以没有,值会默认为Null/0;但是SQL结果里面有的列名必须在Model中存在。否则会报错!
这只是简单的使用,更深层次的需求请参考再谈使用Emit把Datatable转换为对象集合(List) - lindping
原文链接 http://huisky.com/blog/17010514150692
参考资料
- DataTable转Entity(Emit版) - ShuLin
- 使用Emit把Datatable转换为对象集合(List) - lindping
- 再谈使用Emit把Datatable转换为对象集合(List) - lindping
0 0
- 自用的基于Emit的C#下DataTable转实体类方法
- c# 反射得到实体类的字段名称和值,DataTable转List<T>
- C#抽象类及其方法的学习(自用)
- C# Datatable的Select方法
- DataTable到实体类的转换
- Datatable 转 实体类
- c# 把企业库返回的DataTable转换成实体列表
- CYQ.Data V4.5.5 版本发布[顺带开源Emit编写的快速反射转实体类FastToT类]
- DataTable转Entity(Emit版)
- DataTable to Entity - DataTable 转 实体类
- 基于实体分析的数据仓库构建方法
- C# DataTable 和List之间相互转换的方法[转]
- C# IList转换为datatable的方法
- C# DataRow[]转化为DataTable的方法
- c#的DataTable.DefaultView.Sort 排序方法
- C#将多个DataTable合并的方法
- C# Datatable的Select方法(2)
- Vue $emit()不触发方法的原因
- 2016我都做了什么
- 码农成长记——js(表单元素之select)
- 学python第一天---第一个python程序
- Android热修复
- unity 编辑器界面能调用OnGUI和Update等函数
- 自用的基于Emit的C#下DataTable转实体类方法
- 产品运营中的AARRR模型
- ranges的使用
- 图片和二进制转化
- 论文学习笔记-Alexnet
- socket的UDP通信简单例子
- 快速排序(递归)
- 【网络流24题】火星探险问题
- 如何在 Android 中使用 Java8