AutoMapper
允许你在属性映射之前添加条件到必须满足的属性。
这可以用在像下面这样的情况下,我们试图从int
映射到unsigned int
。
class Foo{
public int baz;
}
class Bar {
public uint baz;
}
在下面的映射中,属性baz只会在源对象中大于或等于0时被映射。
Mapper.Initialize(cfg => {
cfg.CreateMap<Foo,Bar>()
.ForMember(dest => dest.baz, opt => opt.Condition(src => (src.baz >= 0)));
});
前提条件
同样,还有一个先决条件。 不同之处在于它在映射过程中运行得更早,源值解析之前(认为MapFrom
或ResolveUsing
)。 所以前提条件被调用,然后我们决定哪个是映射源(解析),然后调用条件,最后是目标值的赋值。 你可以自己看到步骤。
开放泛型
AutoMapper可以支持一个开放的泛型类型映射。 为打开的泛型类型创建一个映射:
public class Source<T> {
public T Value { get; set; }
}
public class Destination<T> {
public T Value { get; set; }
}
//创建映射
Mapper.Initialize(cfg => cfg.CreateMap(typeof(Source<>), typeof(Destination<>)));
您不需要为封闭泛型类型创建映射。 AutoMapper
在运行时将打开的通用映射中的任何配置应用于封闭的映射:
var source = new Source<int> { Value = 10 };
var dest = mapper.Map<Source<int>, Destination<int>>(source);
dest.Value.ShouldEqual(10);
因为C#
只允许关闭泛型类型参数,所以必须使用System.Type
版本的CreateMap
来创建开放的泛型类型映射。 从那里,您可以使用所有可用的映射配置,并在运行时将打开的通用配置应用于封闭的类型映射。 在配置验证过程中,AutoMapper将跳过打开的泛型类型映射,因为您仍然可以创建不转换的封闭类型,例如Source<Foo>
-> Destination<Bar>
,其中没有从Foo转换为Bar。
您也可以创建一个开放的泛型类型转换器:
Mapper.Initialize(cfg =>
cfg.CreateMap(typeof(Source<>), typeof(Destination<>)).ConvertUsing(typeof(Converter<>)));
AutoMapper还支持具有许多通用参数的开放泛型类型转换器:
Mapper.Initialize(cfg =>
cfg.CreateMap(typeof(Source<>), typeof(Destination<>)).ConvertUsing(typeof(Converter<,>)));
来自Source
的封闭类型将是第一个泛型参数,而封闭类型的Destination
将是关闭Converter<,>
的第二个参数。
了解你的映射
AutoMapper为您的映射创建一个执行计划。 执行计划可以在调试过程中被看作表达式树。 您可以通过安装ReadableExpressions
VS扩展来更好地查看生成的代码。 如果您需要查看VS之外的代码,则可以直接使用ReadableExpressions
包。
var configuration = new MapperConfiguration(cfg => cfg.CreateMap<Foo, Bar>());
var executionPlan = configuration.BuildExecutionPlan(typeof(Foo), typeof(Bar));
发布之前一定要删除所有这些代码。
对于ProjectTo
,您需要检查IQueryable.Expression
。
var expression = context.Entities.ProjectTo<Dto>().Expression;