I am trying to use AutoMapper to map between two models in an expression, but receiving an error from AutoMapper: "Error Mapping Types" with an Inner Exception Message of "Object reference not set to an instance of an object."
I set up my configuration and defined the mapping by following the wiki on Github:
Below is a very simplified example that produces the error using version AutoMapper 5.1.1.
Models to Map
Note: I only need to map from Model1 to Model2.
public class Model1
{
public int Id { get; set; }
}
public class Model2
{
public int Id { get; set; }
}
Configuration:
public static class AutoMapperConfig
{
public static IMapper Mapper;
static AutoMapperConfig()
{
var config = new MapperConfiguration(c => {
// Produces error
CreateMap<Model1, Model2>();
//The below definitions do NOT produce error
CreateMap<Model1, Model2>().ReverseMap();
//OR
CreateMap<Model1, Model2>();
CreateMap<Model2, Model1>();
//OR
CreateMap<Expression<Func<Model1,bool>>, Expression<Func<Model2,bool>>>();
});
Mapper = config.CreateMapper();
}
}
Usage:
Expression<Func<Model1, bool>> model1Expr = x => x.Id == 2;
var model2Expr = AutoMapperConfig.Mapper.Map<Expression<Func<Model2,bool>>>(model1Expr);
I receive the error at the line that declares the model2Expr variable above.
Error From Elmah :(
[NullReferenceException: Object reference not set to an instance of an object.]
AutoMapper.Mappers.MappingVisitor.PropertyMap(MemberExpression node) +109
AutoMapper.Mappers.MappingVisitor.VisitMember(MemberExpression node) +95
System.Linq.Expressions.MemberExpression.Accept(ExpressionVisitor visitor) +14
System.Linq.Expressions.ExpressionVisitor.Visit(Expression node) +22
AutoMapper.Mappers.MappingVisitor.VisitBinary(BinaryExpression node) +73
System.Linq.Expressions.BinaryExpression.Accept(ExpressionVisitor visitor) +14
System.Linq.Expressions.ExpressionVisitor.Visit(Expression node) +22
AutoMapper.Mappers.ExpressionMapper.Map(TSource expression, ResolutionContext context) +1534
lambda_method(Closure , Object , Object , ResolutionContext ) +183
[AutoMapperMappingException: Error mapping types.
IMPORTANT: A coworker noted that the error is not encountered when two way mapping is defined (with either ReverseMap or two separate CreateMap statements), or when the mapping is defined explicitly as being between to Expression types. The Expression Translation link above does define two way mapping between the models, but does not explicitly mention requiring it.
Question:
Am I somehow messing up the configuration and/or map definition, or are two way mapping definitions required when mapping between objects in expressions and the wiki is just not explicitly stating it?
UPDATE: I opened an issue on AutoMapper GitHub. As of right now it seems that
Yes the order is backwards when doing expression translation.
Basically this means that if you want to map between expressions, create a mapping definition in the opposite direction of your desired mapping:
CreateMap<Model2, Model1>();
//....
Expression<Func<Model1, bool>> model1Expr = x => x.Id == 2;
var model2Expr = AutoMapperConfig.Mapper.Map<Expression<Func<Model2,bool>>>(model1Expr);