32

我今天从 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<TModel>()只是替换一个长度为零的数组,这可以解释异常。

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

更新:

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

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

该类PageOfEstablishmentApiModel继承自PageOf<EstablishmentApiModel>.

这是 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 需要特殊的映射配置(例如 .ConvertUsing(x => x)),我们可能不得不挂在旧版本上。我一直很喜欢 AM 如何自动转换集合属性,没有它,AM 看起来更像是 ValueInjecter。

4

2 回答 2

1

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

?

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

于 2013-01-23T12:47:48.507 回答
0

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

于 2013-05-25T19:30:11.917 回答