AutoMapper 3中的映射行为不一致

时间:2014-06-27 21:06:00

标签: c# asp.net-mvc entity-framework automapper automapper-3

AutoMapper 3在MVC 5的某些时候将实体框架中的相关实体映射到视图模型时遇到了问题。我使用EF 6.1.1来获取数据,并且轻量级存储库层来集中查询。这个问题似乎只发生在根实体下的实体的映射属性,但问题是间歇性的。在重建解决方案之后,我发现行为重新开始工作,重建解决方案后行为中断,而不更改发生问题的代码。

我已经在调试器和SQL分析器中对此进行了测试,即使数据未显示在前端,我也可以在SQL分析器中看到实体框架正在加载相关的表。

问题的示例映射

在从存储库层查询数据后,此代码在MVC控制器中执行。然后将视图模型传递给视图进行渲染。

Mapper.CreateMap<Event, EventViewModel>()
    .ForMember(e => e.EventTitleId, opt => opt.MapFrom(x => x.EventTitleType.EventTitleId));
EventViewModel model = Mapper.Map<Event, EventViewModel>(eventItem);

//Fix Up I had to implement to ensure the data gets into the property
model.EventTitleId = eventItem.EventTitleType.EventTitleId;

使用问题映射的另一个示例

在不同控制器操作下的相同基本执行路径,同样的问题。

Mapper.CreateMap<Event, EventViewModel>()
    .ForMember(l => l.EventTitle, opt => opt.MapFrom(x => x.EventTitleType.EventTitle.Title))
    .ForMember(l => l.EventType, opt => opt.MapFrom(x => x.EventTitleType.LkEventType.Title))
    .ForMember(l => l.LocationName, opt => opt.MapFrom(x => x.LkLocation.LocationName));
IEnumerable<EventViewModel> eventList = Mapper.Map<IEnumerable<Event>, IEnumerable<EventViewModel>>(events);

同样,有时这三个属性会获得数据,有时它们不会。

数据模型

这就是数据模型的样子。

The part of the edmx file with the data model for this question

存储库

存储库层包装了实体框架调用,但它并没有抽象出实体框架实体及其带来的问题和好处。项目中的所有存储库都继承了IRepository,我使用该层来集中查询和业务逻辑。

using System.Collections.Generic;

namespace Tools.Repository
{
    /// <summary>
    /// Generic Repository Interface
    /// </summary>
    /// <typeparam name="TClass">Class that the Repository is implemented for.</typeparam>
    public interface IRepository<TClass>
        where TClass : class 
    {
        void SaveChanges();
        TClass Find(params object[] keyValues);
        IEnumerable<TClass> GetAll();
        TClass Add(TClass itemToAdd);
        TClass Update(TClass itemToUpdate);
        TClass Remove(TClass itemToDelete);
    }
}

摘要

我不相信这是一个实体框架延迟加载问题,并且在迫使EF急切加载数据之后,问题仍然存在。实体在映射之前具有调试器中的值,但有时仅将值映射到视图模型。最令人沮丧的是,这个问题似乎并不是由我对视图模型所做的任何改变造成的。

什么可能导致这种不一致的行为?我对AutoMapper 3.2.1和3.1.1都有这个问题。

1 个答案:

答案 0 :(得分:2)

问题是您在使用映射之前创建(配置)映射。现在,首先创建映射并因此占优势是巧合。

AutoMapper documentation说:

  

如果您使用静态Mapper方法,则每个AppDomain只应进行一次配置。这意味着放置配置代码的最佳位置是应用程序启动,例如ASP.NET应用程序的Global.asax文件。

这意味着EventEventViewModel之间只有一个映射,可能应该是您现在拥有的两个映射。

顺便说一下,您可以DynamicMap执行偶尔的映射。