【问题标题】:Automapper Expression Error: Null Reference/Error Mapping Types and ReverseMapAutomapper 表达式错误:空引用/错误映射类型和 ReverseMap
【发布时间】:2016-11-23 04:27:23
【问题描述】:

我正在尝试使用 AutoMapper 在表达式中的两个模型之间进行映射,但收到来自 AutoMapper 的错误:“错误映射类型”以及“对象引用未设置为对象实例”的内部异常消息。

我按照 Github 上的 wiki 设置了配置并定义了映射:

Configuration

Expression Translation

下面是一个非常简化的示例,它使用 AutoMapper 5.1.1 版本产生错误。

要映射的模型

注意:我只需要从Model1映射到Model2即可。

public class Model1
{
    public int Id { get; set; }
}

public class Model2
{
    public int Id { get; set; }
} 

配置:

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();
    }
}

用法:

Expression<Func<Model1, bool>> model1Expr = x => x.Id == 2;
var model2Expr =  AutoMapperConfig.Mapper.Map<Expression<Func<Model2,bool>>>(model1Expr);

我在上面声明 model2Expr 变量的行收到错误。

来自 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.

重要提示:一位同事指出,当定义双向映射(使用 ReverseMap 或两个单独的 CreateMap 语句)或将映射明确定义为介于 to Expression 之间时,不会遇到错误类型。上面的表达式翻译链接确实定义了模型之间的两种方式映射,但没有明确提到需要它。

问题:

我是否以某种方式弄乱了配置和/或映射定义,或者当表达式中的对象之间的映射和 wiki 没有明确说明时需要两种映射定义?


更新: 我在AutoMapper GitHub 上打开了一个问题。 目前看来

是的,在进行表达式翻译时,顺序是倒序的。

这基本上意味着,如果您想在表达式之间进行映射,请在所需映射的相反方向创建映射定义:

CreateMap<Model2, Model1>();
//....
Expression<Func<Model1, bool>> model1Expr = x => x.Id == 2;
var model2Expr =  AutoMapperConfig.Mapper.Map<Expression<Func<Model2,bool>>>(model1Expr);

【问题讨论】:

  • 用法与配置为从Model1对象映射到Model2对象的映射不同。
  • @Win 我只是尝试在表达式本身之间定义一个单向映射,但我没有收到错误。我之前没有尝试过,因为根据我在 Expression Translation wiki 中的理解,对象之间的映射定义就足够了。这可能只是文档不完整的情况吗?
  • Automapper 旨在将一个对象的属性映射到另一个对象。为什么要从 表达式树 映射到另一个?它不应该是 Automapper 的工作。
  • 这是一个highly-related question,可能会提供一些见解。
  • @Win 在我的特定情况下,我有一个 DTO,它是实体模型的表示。我在表示层控制器(ASP.NET MVC)中使用 DTO 创建了一个 lambda 表达式。然后将该 lambda 表达式作为参数传递给业务层方法。然后,业务层方法需要将 DTO 表达式转换/映射为实体模型表达式,以便我可以将它与实体框架一起使用。

标签: c# automapper automapper-5


【解决方案1】:

你需要调用 ReverseMap 如下:

static AutoMapperConfig()
{
    var config = new MapperConfiguration(c => {
      CreateMap<Model1, Model2>().ReverseMap(); // <======
    });

    Mapper = config.CreateMapper();
}

【讨论】:

  • 感谢您的回答。您能否提供说明需要 ReverseMap 的文档?我的同事注意到了和你一样的东西,我只是想知道为什么它不在 wiki 中。
  • ReverseMap 默认不提供。它已添加到 AutoMapper,您必须调用它来创建它。这是他们这样做时的提交:github.com/AutoMapper/AutoMapper/commit/…
  • 对不起,我的意思是问是否有文档说明必须定义两种方式映射(使用 ReverseMap 或使用两个单独的 CreateMap 语句)才能使表达式之间的映射正常工作。跨度>
  • 我理解你的问题。他们继续实施 ReverseMap 方法的事实意味着它不存在。如果你不定义反向映射,它也不适用于常规对象,更不用说表达式了。
  • 我没有考虑在我的地图定义中使用 ReverseMap,因为我不需要它。我只需要从 Model1 映射到 Model2。如果表达式映射在 AutoMapper 中工作需要两种方式的映射定义,这对我来说并不直观,尽管这可能是由于我公认的表达式树如何工作的知识有限。感谢您的澄清。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-09-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-09
相关资源
最近更新 更多