自用的基于Emit的C#下DataTable转实体类方法
2017-01-05 19:11
344 查看
自用的基于Emit的C#下DataTable转实体类方法
之前一直在做WebForm的开发,数据绑定时直接DataTable绑定Gridview很方便,但是最近开始往MVC转,数据列表的传递和页面展示基本上是以List为主,像下面这样,遍历实体类的各个字段去赋值的办法当然是最浪费时间的。
通过在网上查资料和一定的比较,我选择了以下基于Emit的DataTable转实体类的方法。
按照下边的代码新建一个类
在DbHelperSQL里面再简单封装一下:
使用的时候:
注意:
- 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
之前一直在做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
相关文章推荐
- 自用的基于Emit的C#下DataTable转实体类方法
- C# DataTable 转换为 实体类对象方法
- 在C#中把两个DataTable连接起来,相当于Sql的Inner Join方法
- C# DataTable.Select()方法,条件中使用类型转换
- C# 中DataTable 的copy()方法和clone()方法
- C# 将内存中的datatable数据导出为Excel(方法二,创建Excel对象导出)
- C# 将内存中的datatable数据导出为Excel(方法一,以文件流方式导出)
- 在C#中把两个DataTable连接起来,相当于Sql的Inner Join方法
- C# DataTable转实体 通用方法
- C# 基于密钥的64位加密与解密方法(原创)
- c#.net实体类序列化方法
- C# 数组转换为DataTable 的三个方法
- c#代码风格——采用合适的方法访问DataTable里的记录
- c#.net实体类序列化方法 为什么序列化
- 在C#中把两个DataTable连接起来,相当于Sql的Inner Join方法
- C# IList转换为datatable的方法
- c#.net实体类序列化方法 为什么要序列化
- c#.net实体类序列化方法 为什么要序列化
- c#.net实体类序列化方法 为什么要序列化
- users实体类包括调用DBHelper中的各种方法,但是没有返回DataTable的方法