AutoMapper映射ExpressionTree
问题描述
项目中使用AutoMapper进行VO&DTO&Entity的互相映射,但是默认Map方法不支持Expression的转换。如
Expression<Func<Entity,bool>> fun = _ => _.A == "A";
希望转换成
Expression<Func<Dto,bool>> fun = _ => _.A == "A";
似乎解决方案就是解析ExpressionTree并映射替换节点。正好找到了人家的提问和解决方案
http://stackoverflow.com/questions/7424501/automapper-for-funcs-between-selector-types
改造一下支持泛型,代码如下:
public static class FunctionCompositionExtensions
{
private static ConcurrentDictionary<Tuple<Type, Type>, Tuple<MethodInfo, Expression>> dictionary = new ConcurrentDictionary<Tuple<Type, Type>, Tuple<MethodInfo, Expression>>();
private static MethodInfo method = typeof(FunctionCompositionExtensions).GetMethod("Compose", BindingFlags.NonPublic | BindingFlags.Static); public static Expression<Func<D, bool>> MapExpression<S, D>(this Expression<Func<S, bool>> selector)
{
var bulidMethod = dictionary.GetOrAdd(new Tuple<Type, Type>(typeof(S), typeof(D)), _ =>
{
var expression = Mapper.Engine.CreateMapExpression<D, S>();
return new Tuple<MethodInfo, Expression>(method.MakeGenericMethod(typeof(D), typeof(bool), typeof(S)), expression);
});
return bulidMethod.Item1.Invoke(null, new[] { selector, bulidMethod.Item2 }) as Expression<Func<D, bool>>; } static Expression<Func<X, Y>> Compose<X, Y, Z>(this Expression<Func<Z, Y>> outer, Expression<Func<X, Z>> inner)
{
return Expression.Lambda<Func<X, Y>>(
ParameterReplacer.Replace(outer.Body, outer.Parameters[0], inner.Body),
inner.Parameters[0]);
} static Expression<Predicate<X>> ComposePredicate<X, Z>(this Expression<Predicate<Z>> outer, Expression<Func<X, Z>> inner)
{
return Expression.Lambda<Predicate<X>>(
ParameterReplacer.Replace(outer.Body, outer.Parameters[0], inner.Body),
inner.Parameters[0]);
}
} class ParameterReplacer : ExpressionVisitor
{
private ParameterExpression _parameter;
private Expression _replacement; private ParameterReplacer(ParameterExpression parameter, Expression replacement)
{
_parameter = parameter;
_replacement = replacement;
} public static Expression Replace(Expression expression, ParameterExpression parameter, Expression replacement)
{
return new ParameterReplacer(parameter, replacement).Visit(expression);
} protected override Expression VisitParameter(ParameterExpression parameter)
{
if (parameter == _parameter)
{
return _replacement;
}
return base.VisitParameter(parameter);
}
}
测试
public class Entity
{
public string A { get; set; }
} public class Dto
{
public string A { get; set; }
} Mapper.CreateMap<Entity, Dto>();
Mapper.CreateMap<Dto, Entity>(); var list = new List<Dto>()
{
new Dto() {A = "A"},
new Dto() {A = "B"},
new Dto() {A = "C"},
new Dto() {A = "D"},
new Dto() {A = "E"},
}; //Predicate<Entity> fun = _ => _.A =="A";
Expression<Func<Entity,bool>> funEntity = _ => _.A == "A"; var query = list.Where(funEntity.MapExpression<Entity, Dto>().Compile());
Assert.True(query.Count() == 1); Expression<Func<Entity, bool>> funEntity2 = _ => _.A == "F";
var query2 = list.Where(funEntity2.MapExpression<Entity, Dto>().Compile());
Assert.True(query2.Count() == 0);
AutoMapper映射ExpressionTree的更多相关文章
- 配置AutoMapper映射规则《转》
配置AutoMapper映射规则 AutoMapper是基于约定的,因此在实用映射之前,我们需要先进行映射规则的配置. public class Source { public int SomeVal ...
- ASP.NET Core搭建多层网站架构【8.2-使用AutoMapper映射实体对象】
2020/01/29, ASP.NET Core 3.1, VS2019, AutoMapper.Extensions.Microsoft.DependencyInjection 7.0.0 摘要:基 ...
- 使用 AutoMapper 映射 IDataReader、DataSet、DataTable 到实体类
AutoMapper是一个.NET的对象映射工具. 项目地址:https://github.com/AutoMapper/AutoMapper. 帮助文档:https://github.com/Aut ...
- 一文为你详细讲解对象映射库【AutoMapper】所支持场景
前言 在AutoMapper未出世前,对象与对象之间的映射,我们只能通过手动为每个属性一一赋值,时间长了不仅是我们而且老外也觉得映射代码很无聊啊.这个时候老外的所写的强大映射库AutoMapper横空 ...
- .NET CORE 中使用AutoMapper进行对象映射
简介 AutoMapper uses a fluent configuration API to define an object-object mapping strategy. AutoMappe ...
- NetCore+AutoMapper多个对象映射到一个Dto对象
目录 一. 定义源映射类和被映射类DTO二.注入AutoMapper三.配置映射四.写测试 一.定义源映射对象 为了体现AutoMapper映射特性,在SocialAttribute中的Name属性没 ...
- 在 ASP.NET Core 项目中使用 AutoMapper 进行实体映射
一.前言 在实际项目开发过程中,我们使用到的各种 ORM 组件都可以很便捷的将我们获取到的数据绑定到对应的 List<T> 集合中,因为我们最终想要在页面上展示的数据与数据库实体类之间可能 ...
- ASP.NET Core Web 应用程序系列(五)- 在ASP.NET Core中使用AutoMapper进行实体映射
本章主要简单介绍下在ASP.NET Core中如何使用AutoMapper进行实体映射.在正式进入主题之前我们来看下几个概念: 1.数据库持久化对象PO(Persistent Object):顾名思义 ...
- ASP.NET CORE 中使用AutoMapper进行对象映射
ASP.NET CORE 中使用AutoMapper进行对象映射 1.什么是AutoMapper? AutoMapper是基于对象到对象约定的映射工具,常用于(但并不仅限制于)把复杂的对象模型转为DT ...
随机推荐
- Backbone之旅——Collection and View篇
上篇文章说了Model,这次说说Collection,collection就是model的集合,用来装载model对象的 定义方法 var Persons = new Backbone.Collect ...
- IIS7 php wordpress 中文url 标签tag中文URL404解决方法
新建重写规则: <rule name="ChineseURL" stopProcessing="true"> <match url=" ...
- Android SDK开发包国内下载地址
不知道是因为最近kaihui还是怎么的,打开android sdk官方网站特别的慢,想下载最新版本的platform几乎变成不可能完成的任务,不知道为什么Google不像Apache那样在各国设立镜像 ...
- cakePHP的controller回调
1. afterFilter(), executed after all controller logic, including the rendering of the view2. beforeF ...
- SQL数据类型解释
SQL数据类型解释 1.char.varchar.text.ntext.bigint.int.smallint.tinyint和bit的区别及数据库的数据类型电脑秘籍 2009-05-15 21:47 ...
- iOS开发工具——网络封包分析工具Charles
简介 Charles是在Mac下常用的截取网络封包的工具,在做iOS开发时,我们为了调试与服务器端的网络通讯协议,常常需要截取网络封包来分析.Charles通过将自己设置成系统的网络访问代理服务器,使 ...
- Spring3 MVC入门示例
Spring3 MVC 介绍: 1. Spring MVC 是Spring 框架的Web组件,能够开发WEB工程 2. 能与其它框架(Struts2)很好的集成 3. Spring MVC 是以se ...
- Tips10:你可以像写文档一样自由的复制粘贴游戏组件(Game Object Component)
相对于添加组件后再进行调整和赋值,通过复制和粘贴已有游戏组件能够带来更高的效率.
- debian系统root用户登录
Debian默认不允许root登录,所以修改之. 让Debian以root登录 1).首先修改gdm3的设定文件(/etc/gdm3/deamon.conf),在[security]字段后面追加如下一 ...
- 免费素材下载:iOS 8 矢量 UI 素材套件
小伙伴们,苹果终于在今天凌晨推送了 iOS 8 的正式版.虽然该系统并未与 iPhone6 发布会同时亮相,但对于已经提前体验尝鲜过测试版的同学来说并不陌生.iOS 8 几乎每个图标都进行了重新设计, ...