C#ORM中的对象映射
使用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中的对象映射的更多相关文章
- django的orm中F对象的使用
今天不巧就用上了. 就是将数据库的字段,自增1的场景. from django.db.models import F DeployPool.objects.filter(name=deployvers ...
- Mybaits的中的对象映射(包含仅有基本数据类型的属性的和对象类型的属性的)
转:https://blog.csdn.net/cjt20100/article/details/46547617. 1 constructor – 用来将结果反射给一个实例化好的类的构造器 a ...
- ASP.NET Core 中的对象映射之 AutoMapper
目录 AutoMapper 简介 AutoMapper 使用 初始化 Profile设置 扁平化映射 集合映射 投影 条件映射 值转换 设置转换前后行为 配置验证及设置 反向映射 自定义转换器 自定义 ...
- ORM中基于对象查询与基于queryset查询
感谢老男孩~ 一步一步走下去 前面是视图函数 后面是表结构models.py from django.shortcuts import render, HttpResponse from djang ...
- odoo ORM中的filed的关系映射的使用详解1
前言 前面我们详细讲解了odoo ORM中fields中的常见属性的使用,根据不同的属性可以对字段进行不同的限制操作,比如readonly只读,store是否存储到数据库.今天我们继续研究ORM中的关 ...
- 一篇搞定SQLAlchemy--关系对象映射
要使用SQLAlchemy,必须先下载这个模块 pip3 install sqlalchemy 或 pycharm File--> Settings-->project...-->P ...
- 【5min+】 对象映射只有AutoMapper?试试Mapster
系列介绍 [五分钟的dotnet]是一个利用您的碎片化时间来学习和丰富.net知识的博文系列.它所包含了.net体系中可能会涉及到的方方面面,比如C#的小细节,AspnetCore,微服务中的.net ...
- [非专业翻译] 高性能对象映射框架 - Mapster
[非专业翻译] 高性能对象映射框架 - Mapster 系列介绍 [非专业翻译] 是对没有中文文档进行翻译的系列博客,文章由机翻和译者自己理解构成,和原文相比有所有不通,但意思基本一致. 因个人能力有 ...
- 对象映射 - Mapping.Mapster
前言 在项目中我们会经常遇到对象的映射,比如像Model和Dto之间的映射,或者是对象的深拷贝,这些都是需要我们自己实现的.此时,项目中会出现很多初始化对象的代码,这些代码写起来相当的枯燥乏味,那么有 ...
随机推荐
- C#3.0新增功能09 LINQ 标准查询运算符 03 按执行方式的分类
连载目录 [已更新最新开发文章,点击查看详细] 标准查询运算符方法的 LINQ to Objects 实现主要通过两种方法之一执行:立即执行和延迟执行.使用延迟执行的查询运算符可以进一步分为两种 ...
- [leetcode] 486. Predict the Winner (medium)
原题 思路: 解法一: 转换比较拿取分数多少的思路,改为考虑 player拿的分数为正,把Player2拿的视为负,加上所有分数,如果最后结果大于0则Player1赢. 思考得出递归表达式: max( ...
- [leetcode] 543. Diameter of Binary Tree (easy)
原题 思路: 题目其实就是求左右最长深度的和 class Solution { private: int res = 0; public: int diameterOfBinaryTree(TreeN ...
- 用margin还是padding ?
margin是用来隔开元素与元素的间距:padding是用来隔开元素与内容的间隔. margin用于布局分开元素使元素与元素互不相干:padding用于元素与内容之间的间隔,让内容(文字)与(包裹)元 ...
- JavaScript基础学习第六天
目标: 能够使用对象的方式处理数据 ☞ 代码预解析: 1. 变量提升 :当程序中遇到定义变量后,就会将该变量的定义提升到当前作用域的开始位置,不包括变量的赋值 2. 函数提升:当程序中遇到函数的声明时 ...
- Apache SSI 远程命令执行漏洞复现
Apache SSI 远程命令执行漏洞复现 一.漏洞描述 当目标服务器开启了SSI与CGI支持,我们就可以上传shtml,利用<!--#exec cmd=”id” -->语法执行命令. 使 ...
- T-SQL 小全
--====================================================== ----数据库概念:创建.删除.使用数据库 ----================= ...
- JS面向对象编程(二):构造函数的继承
对象之间继承的 5 中方法. 比如, 现在有一个"动物"对象的构造函数. function Animal(){ ...
- 使用JavaScript的XMLHttpRequest+fromdata 传递blob到后端
需要上传网页录音文件到服务器,写的艰辛,终于好了,C#端的代码失败的留作纪念,JS端也有失败的案例,就不放上来了 JavaScript: var form = new FormData(); form ...
- 使用hexo中遇到的问题