【问题标题】:Is this a breaking change between AutoMapper 2.0.0 and 2.2.0?这是 AutoMapper 2.0.0 和 2.2.0 之间的重大变化吗?
【发布时间】:2012-11-10 04:51:28
【问题描述】:

我今天从 AutoMapper 2.0.0 更新到 2.2.0 并意识到更新破坏了一些代码。在作为问题发布在 automapper github 网站上之前,想在这里询问一下。

我的目标类型之一像这样初始化集合属性:

public class PageOf<TModel>
{
    public PageOf()
    {
        Items = Enumerable.Empty<TModel>();
    }

    public IEnumerable<TModel> Items { get; set; }
}

使用 automapper 2.0.0,这很好。当我更新到 2.2.0 时,映射到此目标类型会导致 NotSupportedException 并显示消息“集合具有固定大小”。 (该异常被包装在 AutoMapperMappingException 中。)

我能够通过将上面的构造函数代码更改为以下内容来解决此问题:

public PageOf()
{
    Items = new List<TModel>();
}

似乎 AutoMapper 2.0.0 正在丢弃 Items 属性中的任何值并使用 set 属性访问器,而 AutoMapper 2.2.0 只是使用 get 属性访问器并尝试修改现有的 IEnumerable .看起来Enumerable.Empty&lt;TModel&gt;() 只是替换了一个长度为零的数组,这可以解释异常。

这是一个错误吗? AutoMapper 在 2.0.0 和 2.2.0 之间发生了什么变化,会导致它忽略目标属性设置器,而是尝试修改现有集合?

更新:

根据要求,这里是 CreateMap 调用:

public class PagedQueryResultToPageOfItemsProfiler : Profile
{
    protected override void Configure()
    {
        CreateMap<PagedQueryResult<EstablishmentView>, PageOfEstablishmentApiModel>();
    }
}

PageOfEstablishmentApiModel 类继承自 PageOf&lt;EstablishmentApiModel&gt;

这是 Mapper.Map 代码:

var query = Mapper.Map<EstablishmentViewsByKeyword>(input);
var results = _queryProcessor.Execute(query);
var model = Mapper.Map<PageOfEstablishmentApiModel>(results); // exception here

如果 AutoMapper 从 2.0.0 到 2.2.0 需要特殊的映射配置(for example .ConvertUsing(x => x)),我们可能不得不挂在旧版本上。我一直很喜欢 AM 如何自动转换集合属性,没有它,AM 看起来更像是 ValueInjecter。

【问题讨论】:

  • 您也可以发布您的 Automapper 代码吗?即:Mapper.Map 方法调用(您使用的是泛型方法吗?)。这很可能是“设计使然”,并且可以通过正确的映射器方法或映射器配置轻松恢复到您的旧行为。您可以从 automapper 返回一个数组并将其分配给您的 IEnumerable 属性,如 github 上的文档中所示。一旦我看到您执行映射的代码,我将发布一两个示例作为答案。
  • 看起来你在这里不会有太多的运气。我建议你在AutoMapper mailing list 上提问 - 那是专家们闲逛的地方:)
  • 您之前是否查看过 AutoMapper 2.2.0 对保持向后兼容性的支持?在某些情况下,产品的特性/功能已停止(不再受支持),而新版本需要应用重构。

标签: c# collections ienumerable automapper automapper-2


【解决方案1】:

您是否尝试过这样使用 Map 方法: Mapper.Map&lt;DestinationClass, SourceClass&gt;(object to convert)

?

使用 2.2 版 AutoMapper,我们就是这样使用它的,它对我们来说很好用。

【讨论】:

  • 是的,如果您阅读了问题中的代码,那就是我正在做的事情。
  • 对不起,我已经编辑了我的答案,因为没有显示通用类型。想问问你在调用Map方法的时候是否指定了源类和目的类。
【解决方案2】:

我猜它正在尝试添加到您的收藏中,但由于您的收藏是只读实例 (Enumerable.Empty&lt;T&gt;),因此它实际上无法修改它。我假设您是正确的,AutoMapper 更改了有关它们如何实例化新类型的代码。请改用可变实例,例如 new List&lt;T&gt;()T[]

【讨论】:

  • 我不认为T[] 是可变的。这是Enumerable.Empty&lt;T&gt; 默认使用的。
  • 但它可以调整大小/变异,不像 Enumerable.Empty<T>参考是只读的。
  • 上次检查时,数组创建后无法调整大小。它们是固定长度的。您可以将数组转换为列表,更改其大小,然后将其转换回另一个数组,但您不能直接调整数组的大小。
猜你喜欢
  • 2017-06-26
  • 1970-01-01
  • 1970-01-01
  • 2015-01-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-12-17
  • 2015-06-19
相关资源
最近更新 更多