namespace Echofool.Utility.Common {
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq.Expressions;
using System.Reflection;
using System.Reflection.Emit; public class DataTableUtility { public static IEnumerable<T> Get<T>(DataTable table) where T : new() {
if (table == null) {
yield break;
}
if (table.Rows.Count == ) {
yield break;
}
foreach (DataRow row in table.Rows) {
yield return Get<T>(row);
}
} public static T Get<T>(DataRow row) where T : new() {
return GenericCache<T>.Factory(row);
} public class GenericCache<T> where T : new() {
static GenericCache() {
//Factory = GetFactoryIL(); 这里写错了
Factory = GetFactory();
}
public static readonly Func<DataRow, T> Factory; private static Func<DataRow, T> GetFactory() {
var type = typeof(T);
var rowType = typeof(DataRow);
var rowDeclare = Expression.Parameter(rowType, "row");
var instanceDeclare = Expression.Parameter(type, "instance");
var newExpression = Expression.New(type);
var instanceExpression = Expression.Assign(instanceDeclare, newExpression);
var nullEqualExpression = Expression.Equal(rowDeclare, Expression.Constant(null));
var containsMethod = typeof(DataColumnCollection).GetMethod("Contains");
var indexerMethod = rowType.GetMethod("get_Item", BindingFlags.Instance | BindingFlags.Public, null,
new[] { typeof(string) },
new[] { new ParameterModifier() });
var setExpressions = new List<Expression>();
var properties = type.GetProperties(BindingFlags.Instance | BindingFlags.Public);
var columns = Expression.Property(Expression.Property(rowDeclare, "Table"), "Columns");
foreach (var propertyInfo in properties) {
if (propertyInfo.CanWrite) {
var propertyName = Expression.Constant(propertyInfo.Name, typeof(string));
var checkIfContainsColumn =
Expression.Call(columns, containsMethod, propertyName);
var propertyExpression = Expression.Property(instanceDeclare, propertyInfo);
var value = Expression.Call(rowDeclare, indexerMethod, propertyName);
var proertyAssign = Expression.Assign(propertyExpression, Expression.Convert(value, propertyInfo.PropertyType));
setExpressions.Add(Expression.IfThen(checkIfContainsColumn, proertyAssign));
}
}
var checkIfRowIsNull = Expression.IfThenElse(nullEqualExpression, Expression.Empty(), Expression.Block(setExpressions));
var body = Expression.Block(new[] { instanceDeclare }, newExpression, instanceExpression, checkIfRowIsNull, instanceDeclare);
return Expression.Lambda<Func<DataRow, T>>(body, rowDeclare).Compile();
}
} public static T GetByReflection<T>(DataRow dr) where T : new() {
var t = new T();
if (dr != null) {
foreach (var p in typeof(T).GetProperties()) {
if (!dr.Table.Columns.Contains(p.Name)) {
continue;
}
var obj = dr[p.Name];
var set = p.GetSetMethod();
if (set == null) {
continue;
}
p.SetValue(t, obj, null);
}
}
return t;
}
}
}

通过Expression动态构建DataTable映射到实体类,在三层架构中,如果使用的数据层是使用Ado.Net技术,那么加上这个DataTable to Entity的工具类,将为你减少很多代码量。

主要目的是解决DataTable到Entity的映射关系。

         public class MyClass {
public MyClass() { } public MyClass(DataRow row) {
if (row != null) {
if (row.Table.Columns.Contains("Name")) {
this.Name = (string)row["Name"];
}
if (row.Table.Columns.Contains("Age")) {
this.Age = (int)row["Age"];
}
}
} public string Name { get; set; }
public int Age { get; set; } }

如上定义的实体类MyClass,有一个string类型的Name属性和一个int类型的Age属性。

如果自定义构造函数是可以很方便的从DataRow对象中获取数据填充实体类,但如果涉及的实体类太多,而且如果想通过定义特性标记 来实现一些字段特殊处理,构造函数的方式,需要你写太多的代码,而且很多都是重复的逻辑。

现在使用DataTableUtility.Get<MyClass>.Get(row);就能很方便的获取一个实体类。

现在使用DataTableUtility.Get<MyClass>.Get(table);就能很方便的获取一个实体类集合。

Expression构建DataTable to Entity 映射委托的更多相关文章

  1. Expression构建DataTable to Entity 映射委托 sqlserver 数据库里面金额类型为什么不建议用float,实例告诉你为什么不能。 sql server 多行数据合并成一列 C# 字符串大写转小写,小写转大写,数字保留,其他除外 从0开始用U盘制作启动盘装Windows10系统(联想R720笔记本)并永久激活方法 纯CSS打造淘宝导航菜单栏 C# Winform

    Expression构建DataTable to Entity 映射委托   1 namespace Echofool.Utility.Common { 2 using System; 3 using ...

  2. JDK注解替代Hibernate的Entity映射

    1.在entity(实体类)模块中使用注解 1_1.注解的位置出现在 [类定义的前面] 和 [属性的get方法前面] [属性的get方法前面] Java代码: package app.entity; ...

  3. Newtonsoft.Json高级用法,json序列号,model反序列化,支持序列化和反序列化DataTable,DataSet,Entity Framework和Entity,字符串

    原文地址:https://www.cnblogs.com/yanweidie/p/4605212.html 手机端应用讲究速度快,体验好.刚好手头上的一个项目服务端接口有性能问题,需要进行优化.在接口 ...

  4. 数据库查询 - DataTable转Entity类型数据

    当使用Sql语句查询数据库,返回DataSet数据集. DataSet转化为数据列表,可以通过映射方式直接返回Entity数据列表 新建一个特性类,用于数据库列表列名称映射 LinqToDB提供了一个 ...

  5. DataTable转Entity(Emit版)

    public static List<T> ToList<T>(DataTable dt)        {            List<T> list = n ...

  6. C#构建DataTable(转)

    Asp.net DataTable添加列和行的方法 方法一: DataTable tblDatas = new DataTable("Datas"); DataColumn dc ...

  7. List转换为DataTable List<Entity>

    /// <summary> /// 将List转换成DataTable /// </summary> /// <typeparam name="T"& ...

  8. DataTable To Entity

    using System;using System.Collections.Generic;using System.Data;using System.Reflection;using System ...

  9. .net core mysql entity映射时字符串被截断

    参考地址:https://stackoverflow.com/questions/40833262/net-core-entity-framework-mysql-string-fields-stor ...

随机推荐

  1. SignalR Troubleshooting

    This document contains the following sections. Calling methods between the client and server silentl ...

  2. 关于Android读取不同位置(drawable,asset,SDCard)的图片资源的总结

    方式一: 已将图片保存到drawable目录下,通过图片id获得Drawable或者Bitmap,此方式最常用.(若只知道图片的名称,还可以通过图片的名称获得图片的id) (1)通过图片id获得Dra ...

  3. 为兴趣求职:如何学习UI框架,请将你的看法观点写在评论下面

    前言:此篇文章是就我女朋友的求职和前端学习经历而写,希望得到UI前辈的热心指点,不胜感激涕零! 地理坐标: 中国,四川,成都 求职经历: 她之前找过两份工作,第一份是金融销售专员,第二份是汽车保险.她 ...

  4. 51nod-正整数分组问题(基础方程DP-01背包)

    正整数分组 将一堆正整数分为2组,要求2组的和相差最小. 例如:1 2 3 4 5,将1 2 4分为1组,3 5分为1组,两组和相差1,是所有方案中相差最少的. 思路: 这题的实质其实也是0-1背包问 ...

  5. Appnium+python实现手势密码为什么总是报错

    最近一直在尝试Appnium实现Android手机自动化测试,一直一直卡在一个点上,那就是手势密码,因为所测应用的手势密码使用的不是单个的imageview实现的手势密码解锁窗,所以只能靠坐标点来定位 ...

  6. Bonobos | IT桔子

    Trumaker | IT桔子 Trumaker trumaker.com

  7. java笔记3之赋值运算符

    赋值运算符:        基本的赋值运算符:=            把=右边的数据赋值给左边.          扩展的赋值运算符:+=,-=,*=,/=,%=            += 把左边 ...

  8. Eclipse中设置编码的方式

    如果要使插件开发应用能有更好的国际化支持,能够最大程度的支持中文输出,则最好使 Java文件使用UTF-8编码.然而,Eclipse工 作空间(workspace)的缺省字符编码是操作系统缺省的编码, ...

  9. 一维DFT

    学习DIP第3天 傅里叶变换是一个非常大的话题.今天实现了下一维的DFT,兴许将完毕其它傅里叶系的算法实现和实验. DFT公式:                             当中e 是自然 ...

  10. redis 源代码分析(一) 内存管理

    一,redis内存管理介绍 redis是一个基于内存的key-value的数据库,其内存管理是很重要的,为了屏蔽不同平台之间的差异,以及统计内存占用量等,redis对内存分配函数进行了一层封装,程序中 ...