使用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. TCP端口复用引发的异常,用setsockopt来解决

    TCP端口复用引发的异常,用setsockopt来解决 我们在并发连接一个服务端时候他会出现这种情况 OSError: [WinError 10048] 通常每个套接字地址(协议/网络地址/端口)只允 ...

  2. SpringBoot热部署报错(BeanCreationException: Error creating bean with name 'classPathFileSystemWatcher' d)

    springboot热部署配置方法 http://blog.csdn.net/pyfysf/article/details/78791292 异常信息如下 org.springframework.be ...

  3. [剑指offer] 40. 数组中只出现一次的数字

    题目描述 一个整型数组里除了两个数字之外,其他的数字都出现了偶数次.请写程序找出这两个只出现一次的数字. 思路: 解法一: 哈希表 class Solution { public: void Find ...

  4. [蓝桥杯] Fibonacci数列 入门

    原题链接 import java.util.Scanner;//导入Scanner类 public class Main { public static void main(String[] args ...

  5. Makefile简单的配置

    一.文件配置目录 1)原目录 demo ├── Makefile ├── demo.cpp ├── demo.hpp └── main.cpp 2)make之后的目录 demo ├── Makefil ...

  6. Java EE.JSP.概述

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

  7. PHP使用array_unique对二维数组去重处理

    去重,点这里,东西是好东西,就是有点懒.莫见怪

  8. mysql查看视图用户

    select `DEFINER` from  information_schema.VIEWS;

  9. django第四次(转自刘江)

    我们都知道对于ManyToMany字段,Django采用的是第三张中间表的方式.通过这第三张表,来关联ManyToMany的双方.下面我们根据一个具体的例子,详细解说中间表的使用. 一.默认中间表 首 ...

  10. [填坑] ubuntu检测不到外接显示器

    笔记本是win10+ubuntu18双系统,今天ubuntu(开启nivida独显状态)突然无法连外接屏幕,但切换win10就可以显示. 贴吧找到的简单解决方法,不需要重装驱动,记录分享在这里: su ...