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. Android读取Assert文件夹下txt文本并变为String的方法

    使用场景,在assert文件夹下 有些文本文件,我们需要通过工具类读取出来,然后放到String字符串中,我们该如何操作呢: 直接上代码: 使用方法: MyActivity.readAssertRes ...

  2. bzoj3767 A+B Problem加强版

    Description   Input 输入A,B   Output 输出A+B. Sample Input 1 1 Sample Output 2 HINT 对于100%的数据,保证 |A| , | ...

  3. ACM2055_ctype.h_cctype

    #include<iostream> int main() { using namespace std; int y,count; char x; cin>>count; wh ...

  4. SPOJ694 -- DISUBSTR 后缀树组求不相同的子串的个数

    DISUBSTR - Distinct Substrings   Given a string, we need to find the total number of its distinct su ...

  5. [深入react] 4.牛逼闪闪的虚拟DOM

    React.createElement嵌套后的结果就是虚拟dom,虚拟dom听着很高端,其实就是一个json,类似: { type:'div', props:{ className:"box ...

  6. wsdl文件结构分析

    WSDL (Web Services Description Language,Web服务描述语言)是一种XML Application,他将Web服务描述定义为一组服务访问点,客户端可以通过这些服务 ...

  7. 新建cocos2d-xproject

     在cocos2d-x v3.1.1版本号中,採用命令行的方式来创建一个新的project.比方新建一个名为MyGame的project能够用以下的命令: watermark/2/text/aHR ...

  8. IRQL_NOT_LESS_OR_EQUAL的问题最终算攻克了

    今日想提高我那台古董笔记本extensa 4620Z的执行效率.方便我编程. 我先用万能的硬件检測工具,反正也就那几个流氓软件看了下.内存是ddr2的.我也顺带补习了一下许久不碰的硬件知识.ddr2和 ...

  9. html hack 列表

    <!--[if !IE]><!--> 除IE外都可识别 <!--<![endif]--> <!--[if IE]> 所有的IE可识别 <![ ...

  10. .Net HttpClient 模拟登录微信公众平台发送消息

    1.模拟登录 public WeiXinRetInfo ExecLogin(string name, string pass) { CookieContainer cc = new CookieCon ...