使用Linq.Expressions来动态生成映射方法

  1.我们先写个简单的类Test,包含一个ID和Name。

public class Test
{
public int? ID { get; set; }
public string Name { get; set; }
}

  2.需要手工写简单映射代码,暂时不考虑大小写等问题,代码如下。

        /// <summary>
/// 设置属性
/// </summary>
static void Set(Test t,string name,object value)
{
switch (name)
{
case "ID":t.ID = Convert.ToInt32(value);break;
case "Name": t.Name = Convert.ToString(value); break;
}
}
/// <summary>
/// 获取属性
/// </summary>
static Object Get(Test t, string name)
{
switch (name)
{
case "ID": return t.ID;
case "Name": return t.Name;
}
return null;
}

  3.目标就是通过Expressions来自动产生上面2个方法,先定义Set方法的3个参数Test ,name,value(不了解Expressions点击

ParameterExpression val = Expression.Parameter(typeof(object));//value
ParameterExpression instance = Expression.Parameter(typeof(object));//Test 
ParameterExpression nameexp = Expression.Parameter(typeof(string));//name

  4.通过反射得到所有的属性集合,再根据属性集合产生case 语句,以下为Set方法的表达式

var ps = t.GetProperties();//t为typeof(Test)
List<SwitchCase> lt = new List<SwitchCase>();
foreach (var n in ps)
{
if (!n.CanWrite) { continue; }
Expression tp = Expression.Convert(val, n.PropertyType); //类型转换,此为隐式转换。目前不考虑强行转换类型
lt.Add(Expression.SwitchCase(Expression.Call(Expression.Convert(instance, t), n.GetSetMethod(), tp), Expression.Constant(n.Name)));
 }
Expression p1 = Expression.Switch(nameexp, lt.ToArray());
LambdaExpression exp = Expression.Lambda(p1, instance, nameexp, val);//转换为LambdaExpression 后就可以编译了
Action<object, string, object> act = exp.Compile() as Action<object, string, object>;

  5.Get方法的表达式

var ps = t.GetProperties();
List<SwitchCase> lt = new List<SwitchCase>();
ParameterExpression instance = Expression.Parameter(typeof(object));
ParameterExpression nameexp = Expression.Parameter(typeof(string));
foreach (var n in ps)
{
if (!n.CanRead) { continue; }
lt.Add(Expression.SwitchCase(Expression.Convert(Expression.Call(Expression.Convert(instance, t), n.GetGetMethod(), null), typeof(object)), Expression.Constant(n.Name)));
}
Expression p1 = Expression.Switch(nameexp, Expression.Constant(null), lt.ToArray());
LambdaExpression exp = Expression.Lambda(p1, instance, nameexp);
Func<object, string, object> func = exp.Compile() as Func<object, string, object>;

  以上只是简单的案例代码,用于说明Expression来产生映射代码,查看完整代码,虽然更多人用Emit,但本质是一样。

C#ORM中的对象映射的更多相关文章

  1. django的orm中F对象的使用

    今天不巧就用上了. 就是将数据库的字段,自增1的场景. from django.db.models import F DeployPool.objects.filter(name=deployvers ...

  2. Mybaits的中的对象映射(包含仅有基本数据类型的属性的和对象类型的属性的)

    转:https://blog.csdn.net/cjt20100/article/details/46547617. 1 constructor – 用来将结果反射给一个实例化好的类的构造器    a ...

  3. ASP.NET Core 中的对象映射之 AutoMapper

    目录 AutoMapper 简介 AutoMapper 使用 初始化 Profile设置 扁平化映射 集合映射 投影 条件映射 值转换 设置转换前后行为 配置验证及设置 反向映射 自定义转换器 自定义 ...

  4. ORM中基于对象查询与基于queryset查询

    感谢老男孩~  一步一步走下去 前面是视图函数 后面是表结构models.py from django.shortcuts import render, HttpResponse from djang ...

  5. odoo ORM中的filed的关系映射的使用详解1

    前言 前面我们详细讲解了odoo ORM中fields中的常见属性的使用,根据不同的属性可以对字段进行不同的限制操作,比如readonly只读,store是否存储到数据库.今天我们继续研究ORM中的关 ...

  6. 一篇搞定SQLAlchemy--关系对象映射

    要使用SQLAlchemy,必须先下载这个模块 pip3 install sqlalchemy 或 pycharm File--> Settings-->project...-->P ...

  7. 【5min+】 对象映射只有AutoMapper?试试Mapster

    系列介绍 [五分钟的dotnet]是一个利用您的碎片化时间来学习和丰富.net知识的博文系列.它所包含了.net体系中可能会涉及到的方方面面,比如C#的小细节,AspnetCore,微服务中的.net ...

  8. [非专业翻译] 高性能对象映射框架 - Mapster

    [非专业翻译] 高性能对象映射框架 - Mapster 系列介绍 [非专业翻译] 是对没有中文文档进行翻译的系列博客,文章由机翻和译者自己理解构成,和原文相比有所有不通,但意思基本一致. 因个人能力有 ...

  9. 对象映射 - Mapping.Mapster

    前言 在项目中我们会经常遇到对象的映射,比如像Model和Dto之间的映射,或者是对象的深拷贝,这些都是需要我们自己实现的.此时,项目中会出现很多初始化对象的代码,这些代码写起来相当的枯燥乏味,那么有 ...

随机推荐

  1. Spring MVC + Spring + MyBatis 框架整合

    本文介绍使用SSM框架开发web项目Demo. 一.创建一个web-Poject项目 1.导入相关jar文件至lib下.“相关jar文件” --提取密码 oraw 2.修改web.xml文件 < ...

  2. SpringBoot集成beetl模板快速入门

    SpringBoot集成beetl模板快速入门 首次探索 beetl官方网址:http://ibeetl.com/ 创建SpringBoot工程(idea) 新建工程 选择创建Spring工程 书写包 ...

  3. Nodejs监控Apple召回计划&邮件提醒

    最近,我的MacBook Pro 2015款13寸电池膨胀了 把笔记本平放在桌面,四个脚中的前两个无法落地,笔记本盖合上之后,屏幕上会印上键盘的纹路,也就是说,笔记本C面D面变形了,已经购买超过3年, ...

  4. HttpWebRequest的使用之Get和Post的差别(C#)

    这两天做的是通过一个HttpWebRequest将采集地址发送到服务端,服务端会返回一个JSON格式的字符串,然后我这边再对这个JSON进行反序列化,得到我想要的数据.在这篇文章里我简单介绍一下Htt ...

  5. Java EE.JSP.概述

    JSP最终会被转换成标准Servlet,该转换过程一般出现在第一次请求页面时. JSP页面的主要组成部分如下: HTML 脚本:嵌入Java代码 指令:从整体上控制Servlet的结构 动作:引入现有 ...

  6. 如何在 Centos7 中安装 Mysql 5.7

    一.下载安装包 (1). 下载MySQL源码 (进入/usr/local/src目录,使用wget下载) cd /usr/local/src wget https://dev.mysql.com/ge ...

  7. 深入分析Elastic Search的写入过程

    摘要 之前写过一篇ElasticSearch初识之吐槽,不知觉竟然过去了两年了.哎,时光催人老啊.最近又用到了ES,想找找过去的总结文档,居然只有一篇,搞了半年的ES,遇到那么多的问题,产出只有这么点 ...

  8. spark 源码分析之八--Spark RPC剖析之TransportContext和TransportClientFactory剖析

    spark 源码分析之八--Spark RPC剖析之TransportContext和TransportClientFactory剖析 TransportContext 首先官方文档对Transpor ...

  9. bean的创建(五)第一部分

    AbstractBeanFactory.doGetBean protected <T> T doGetBean( final String name, final Class<T&g ...

  10. 【iOS】the executable was signed with invalid entitlements

    又遇到了这个问题,貌似之前遇到过,如图所示: 原因:开发证书里没添加手机. PS: Xcode7 除外,据说已经不需要证书了,这里用的是 6.4