Expression构建DataTable to Entity 映射委托
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 映射委托的更多相关文章
- 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 ...
- JDK注解替代Hibernate的Entity映射
1.在entity(实体类)模块中使用注解 1_1.注解的位置出现在 [类定义的前面] 和 [属性的get方法前面] [属性的get方法前面] Java代码: package app.entity; ...
- Newtonsoft.Json高级用法,json序列号,model反序列化,支持序列化和反序列化DataTable,DataSet,Entity Framework和Entity,字符串
原文地址:https://www.cnblogs.com/yanweidie/p/4605212.html 手机端应用讲究速度快,体验好.刚好手头上的一个项目服务端接口有性能问题,需要进行优化.在接口 ...
- 数据库查询 - DataTable转Entity类型数据
当使用Sql语句查询数据库,返回DataSet数据集. DataSet转化为数据列表,可以通过映射方式直接返回Entity数据列表 新建一个特性类,用于数据库列表列名称映射 LinqToDB提供了一个 ...
- DataTable转Entity(Emit版)
public static List<T> ToList<T>(DataTable dt) { List<T> list = n ...
- C#构建DataTable(转)
Asp.net DataTable添加列和行的方法 方法一: DataTable tblDatas = new DataTable("Datas"); DataColumn dc ...
- List转换为DataTable List<Entity>
/// <summary> /// 将List转换成DataTable /// </summary> /// <typeparam name="T"& ...
- DataTable To Entity
using System;using System.Collections.Generic;using System.Data;using System.Reflection;using System ...
- .net core mysql entity映射时字符串被截断
参考地址:https://stackoverflow.com/questions/40833262/net-core-entity-framework-mysql-string-fields-stor ...
随机推荐
- 对Primary-backup分布式数据库分布式一致性的猜想
昨天读了paxos算法,心里对分布式一致性有一些想法:如果是我,应该怎么实现数据库集群的一致性呢? paxos算法本身并没有提到其应用,所以实际使用情况应该较复杂.而我平时接触到使用分布式一致性算法的 ...
- U-Boot启动过程完全分析
U-Boot启动过程完全分析 1.1 U-Boot工作过程 U-Boot启动内核的过程可以分为两个阶段,两个阶段的功能如下: (1)第一阶段的功能 硬件设备初始化 加载U-Boot第二阶段 ...
- P2P网贷投资须谨防圈钱人
摘要:P2P领域依然呈现投资热潮,甚至部分国有大行也有意涉足.这个行业到底怎么了?P2P平台上高收益的理财产品,到底能买不? 新年才刚刚过了10天,就有4家网贷平台被爆出支付危机,P2P一时被 ...
- Delphi 在使用exports中的方法 带参数的用法
最近项目中,需要在一个bpl中调用另一个bpl中的单元的方法, 方法如下: 在被调用的单元中定义: procedure Inner_Ex(VoucherType: TVoucherType); exp ...
- 探求Floyd算法的动态规划本质(转)
---恢复内容开始--- Floyd–Warshall(简称Floyd算法)是一种著名的解决任意两点间的最短路径(All Paris Shortest Paths,APSP)的算法.从表面上粗看,Fl ...
- Javascript Promise 学习笔记
1. 定义:Promise是抽象异步处理对象以及对其进行各种操作的组件,它把异步处理对象和异步处理规则采用统一的接口进行规范化. 2. ES6 Promises 标准中定义的API: ...
- 常用的MIME类型(资源的媒体类型)
后缀名 MIME名称 *.3gpp audio/3gpp, video/3gpp *.ac3 audio/ac3 *.asf allpication/vnd.ms-asf *.au audio/bas ...
- JS浏览器对象-计时器
setInterval用法 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> ...
- 【80端口占用】win7下80端口被(Pid=4)占用的解决方法
亲测可用 通过cmd命令查询占用进程的pid netstat -ano 如果要是tomcat等一般程序占用了端口,一般pid比较大,直接找到相应的pid结束掉进程就行啦. 但是如果pid是4,代表sy ...
- 【C#基础】CSA控件编写秘籍
新建CSA控件 1.新建一个纯类,命名空间是: namespace SimPerfect.CSAControlLibrary.CSAControls 2.实现两个构造函数:无参和传Candy参数 pu ...