使用AutoMapper时Expression的转换
此文章为转载:http://www.bubuko.com/infodetail-699735.html
参考链接:
http://q.cnblogs.com/q/34480/ dudu有回复,其中一个链接http://stackoverflow.com/questions/7424501/automapper-for-funcs-between-selector-types可以打开,并且本人主要参考此链接进行修改
下文链接为automapper相关源码
http://www.symbolsource.org/Public/Metadata/NuGet/Project/AutoMapper/3.3.0-ci1017/Release/Unsupported,Version%3Dv0.0/AutoMapper/AutoMapper/Internal/MappingExpression.cs?ImageName=AutoMapper
以下为转载内容:
问题描述
项目中使用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
改造一下支持泛型,代码如下:
#region using namespace using System;
using System.Collections.Concurrent;
using System.Linq.Expressions;
using System.Reflection;
using AutoMapper;
using AutoMapper.QueryableExtensions; #endregion namespace Core
{
public static class FunctionCompositionExtensions
{
private static readonly ConcurrentDictionary<Tuple<Type, Type>, Tuple<MethodInfo, Expression>> Dictionary =
new ConcurrentDictionary<Tuple<Type, Type>, Tuple<MethodInfo, Expression>>(); private static readonly MethodInfo Method = typeof (FunctionCompositionExtensions).GetMethod("Compose",
BindingFlags.NonPublic | BindingFlags.Static); public static Expression<Func<TDestination, bool>> MapExpression<TSource, TDestination>(
this Expression<Func<TSource, bool>> selector)
{
var bulidMethod = Dictionary.GetOrAdd(new Tuple<Type, Type>(typeof (TSource), typeof (TDestination)), _ =>
{
var expression = Mapper.Engine.CreateMapExpression<TDestination, TSource>();
return new Tuple<MethodInfo, Expression>(
Method.MakeGenericMethod(typeof (TDestination), typeof (bool), typeof (TSource)), expression);
});
return
bulidMethod.Item1.Invoke(null, new object[] {selector, bulidMethod.Item2}) as
Expression<Func<TDestination, bool>>;
} public static Expression<Func<TX, TY>> Compose<TX, TY, TZ>(this Expression<Func<TZ, TY>> outer,
Expression<Func<TX, TZ>> inner)
{
return Expression.Lambda<Func<TX, TY>>(
ParameterReplacer.Replace(outer.Body, outer.Parameters[], inner.Body),
inner.Parameters[]);
} public static Expression<Predicate<TX>> ComposePredicate<TX, TZ>(this Expression<Predicate<TZ>> outer,
Expression<Func<TX, TZ>> inner)
{
return Expression.Lambda<Predicate<TX>>(
ParameterReplacer.Replace(outer.Body, outer.Parameters[], inner.Body),
inner.Parameters[]);
}
} class ParameterReplacer : ExpressionVisitor
{
private readonly ParameterExpression _parameter;
private readonly 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() == ); Expression<Func<Entity, bool>> funEntity2 = _ => _.A == "F";
var query2 = list.Where(funEntity2.MapExpression<Entity, Dto>().Compile());
Assert.True(query2.Count() == );
使用AutoMapper时Expression的转换的更多相关文章
- 一对多关系domain Model中设置使用AutoMapper时出错
在使用AutoMapper时,把数据从VO-PO时显示如下错误,错误提示说在一对多关系中已将集合设置为EntityCollection,那么这个是为什么呢. 看下action中的代码,我们可以发现这是 ...
- 使用C/C++,赋值运算时发生的转换
使用C/C++,赋值运算时发生的转换主要有以下四种情况 一: 两边类型不同: 结果: 自动完成类型转换! 二: 长数赋给短数: 结果: 截取长数的低位送给短数! 三: 短数赋给长数: 结果: 原来是什 ...
- PowerDesigner中转换物理模型时的命名转换
原文:PowerDesigner中转换物理模型时的命名转换 最近在使用PowerDesigner建模数据库,在使用中积累了一些遇到的问题和解决办法,记录下来,希望对遇到同样问题的朋友有所帮助. 早 期 ...
- C语言中以文本方式读写文件时换行符转换的注意事项
我们知道在UNIX下是没有回车符(\r)的,只有换行符(\n),而C语言诞生于UNIX(Linux即面向开源的UNIX,Mac OS也是UNIX发展而来的,而Windows是从MS-DOS发展而来,与 ...
- Swift3 根据秒数获取视频时长(转换成00:00:00时间格式)以及将时长转换成秒
直接代码了: /// 秒转换成00:00:00格式 /// /// - Parameter secounds: <#secounds description#> /// - Returns ...
- Angular js 双向绑定时字符串的转换成 数字类型的问题
问题: <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <scrip ...
- VC2010编译时提示:转换到 COFF 期间失败: 文件无效或损坏
有时候新安装好VS2010后编译时就提示上述错误,罗列一下从网上查找到的几种解决方案: 方案1: 点击“项目”-->“属性”--> “清单工具”, 然后选择"输入和输出’--&g ...
- 使用BeanUtils封装数据时数据类型的转换
//获得表单数据 Map<String, String[]> properties = request.getParameterMap(); User user = new User(); ...
- .Net Core2.2 使用 AutoMapper进行实体转换
一.遇到的问题 在. Core Api 的编写中,我们经常会对一些功能点进行新增编辑操作,同时我们有时也会进行查询,但是我们查询的表的数据与我们返回的数据相差甚大,这是我们有需要自己手动进行类型的转换 ...
随机推荐
- hive类型转化错误,会错误提示指定分区参数
select * from TRAD_LIST t WHERE t.dt >= '2017-10-18' and t.dt <= '2017-11-01' and t.con_level ...
- python-html-百度云音视频点播服务
加密的视频: 一:python后端需要生成token token计算规则 名词解释: userId: 百度云用户唯一标识,可在百度云管理控制台账号基本信息中得到,32位字符串. userKey:用户密 ...
- ftp的安全问题
ftp漏洞http://www.4hou.com/technology/3507.html
- python中enumerate、变量类型转换
enumerate可以在遍历过程中自动生成新的一列并从0开始计数 1 a = ["hello", "world", "dlrb"] 2 fo ...
- 一个简单的python登录验证系统
希望大家来指正一下,之前间断学习了很久,刚捡起来继续学习,下面的代码写的不太好,希望看到的大神能够给予指正. 修正版: 1 # python_zhangzengqiang 2 3 a = open ...
- <转载> js 闭包
http://www.haorooms.com/post/js_bbtwo http://www.jb51.net/article/24101.htm http://www.cnblogs.com/f ...
- Dagger2使用
初衷 Dagger2的初衷就是通过依赖注入让你少些很多公式化代码,更容易测试,降低耦合,创建可复用可互换的模块.你可以在Debug包,测试运行包以及release包优雅注入三种不同的实现. 依赖注入 ...
- PHP 字符串两边填充补零
str_pad顾名思义这个函数是针对字符串来说的这个可以对指定的字符串填补任何其它的字符串 例如:str_pad(带填补的字符串,填补后的长度,填补字符串,填补位置) 其中填补后的长度必须是个正整数, ...
- 机器学习入门-文本数据-构造词频词袋模型 1.re.sub(进行字符串的替换) 2.nltk.corpus.stopwords.words(获得停用词表) 3.nltk.WordPunctTokenizer(对字符串进行分词操作) 4.np.vectorize(对函数进行向量化) 5. CountVectorizer(构建词频的词袋模型)
函数说明: 1. re.sub(r'[^a-zA-Z0-9\s]', repl='', sting=string) 用于进行字符串的替换,这里我们用来去除标点符号 参数说明:r'[^a-zA-Z0- ...
- Srping cloud Ribbon 自定义负载均衡
IRule 默认提供有7种方式,使用轮询方式 如何自定义 1:主启动类加@RibbonClient @RibbonClient(name="微服务名", configuration ...