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 ...
随机推荐
- QT的文本加密方法(寒山居士)
http://blog.csdn.net/esonpo/article/details/12746315http://blog.csdn.net/esonpo/article/details/1174 ...
- 2个Web上传组件
http://www.uploadify.com/download/ http://gmupload.tanjun.com.cn/
- TCP粘包的拆包处理
因为TCP是流式处理的,所以包没有边界,必须设计一个包头,里面表示包的长度(一般用字节表示),根据这个来逐个拆包.如果对于发送/接收频率不高的话,一般也就不做拆包处理了,因为不大可能有粘包现象. 以下 ...
- vector,list和deque区别
stl提供了三个最基本的容器:vector,list,deque. vector和built-in数组类似,它拥有一段连续的内存空间,并且起始地址不变,因此它能非常好的支持随即存取,即[]操作符,但由 ...
- VS2008 运行VC\Bin下的link.exe, cl.exe, lib.exe提示找不到mspdb80.dll的解决方法
天在用link.EXE的LIB命令生成用于连接(LINK)使用的lib文件时提示:找不到mspdb80.dll. 原因:Microsoft Visual Studio\VC\Bin\下没有 “msob ...
- Raid1源代码分析--写流程
正确写流程的总体步骤是,raid1接收上层的写bio,申请一个r1_bio结构,将其中的所有bios[]指向该bio.假设盘阵中有N块盘.然后克隆N份上层的bio结构,并分别将每个bios[]指向克隆 ...
- mysql-创建函数,存储过程以及视图
1.创建函数 mysql>delimiter // mysql>create function 函数名(参数1 参数1类型,...) returns 返回类型 >be ...
- WINDOWS BITLOCK
BitLocker是什么? Windows BitLocker驱动器加密通过加密Windows操作系统卷上存储的所有数据可以更好地保护计算机中的数据.BitLocker使用TPM帮助保护Windows ...
- 白话C#:特性(转)
不管怎么样,转过来再说. http://www.kuqin.com/dotnet/20080628/10196.html 系列文章索引:<白话C#> 首先要说的是,可能一些刚接触C#的朋友 ...
- Java学习之List接口
List接口 List接口的定义如下: public interface List<E>extends Collection<E> 可以发现List接口时Collection接 ...