MVC和Automapper多级嵌套

时间:2012-12-19 06:02:09

标签: asp.net-mvc automapper

我开始使用MVC和自动映射器并希望得到一些指导。我有一些域模型和视图模型,它们是这些域模型的组合。基本上有4个班级

Transcription有一个关联的Audio,由Client Staff拥有Users

中的用户ID

数据库关系图:

http://i49.tinypic.com/whcwsz.jpg

生成的域模型EF(仅限相关字段)

public class audio
{
    public int AudioID { get; set; }
    public string AudioLength { get; set; }
    public virtual ClientStaff ClientStaff { get; set; }
    public virtual ICollection<Transcription> Transcriptions { get; set; }
}

public class ClientStaff
{
    public int ClientStaffID { get; set; }
    public int StaffType { get; set; }
    public int ClientID { get; set; }
    public virtual ICollection<Audio> Audios { get; set; }
    public virtual User User { get; set; }
}

public class User
{
    public int UserID { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }    
    public virtual ICollection<ClientStaff> ClientStaffs { get; set; }
}

public class Transcription
{
    public int TranscriptionID { get; set; }
    public string TranscriptionText { get; set; }
    public virtual Audio Audio { get; set; }
    public Nullable<int> AudioID { get; set; }
}

查看模型

public class customVM
{
    public int AudioID { get; set; }//get from audio
    public string Path { get; set; }//get from audio
    public string AudioLength { get; set; }//get from audio
    public DateTime AudioCreatedOn { get; set; }//get from audio
    public int ClientStaffID { get; set; }//get from audio
    public string TranscriptionText { get; set; }//get from transcription
    public DateTime TranscriptionCreatedOn { get; set; }//get from transcription
    public string UsersFirstName { get; set; }//get from users
    public string UsersLastName { get; set; }//get from users 
}

控制器操作

public ActionResult Index()
{
    IEnumerable<Audio> x= db.getAudioFiles();
    Mapper.CreateMap<Audio, customVM>();
    IEnumerable<customVM> model =
        Mapper.Map<IEnumerable<Audio>, IEnumerable<customVM>>(x);
    Mapper.AssertConfigurationIsValid();

    return View(model);
}

问题:

AutoMapper正在从TranscriptionClientStaff获取属性,但如何获取用户的名字和姓氏?或者更确切地说,如何使用自动映射器获得第二级嵌套类属性。或者我是否错误地处理了整个问题?

1 个答案:

答案 0 :(得分:2)

您需要明确定义它。例如:

Mapper.CreateMap<Audio, customVM>()
    .ForMember(dest => dest.UsersFirstName,
               opt => opt.MapFrom(src => src.ClientStaff.User.FirstName))
    .ForMember(dest => dest.UsersLastName,
               opt => opt.MapFrom(src => src.ClientStaff.User.LastName));

此外,我相信您不需要在地图中指定IEnumerable,但我还没有对其进行测试。也就是说,我已被告知这应该有效:

IEnumerable<customVM> model= Mapper.Map<Audio, customVM>(x);

它并不过分重要,但会稍微清理一下代码。

除此之外,您应该只配置映射一次,而不是在操作中使用映射配置。最好的方法是使用配置文件:

public class MyProfile : Profile
{
    public override string ProfileName
    {
        get
        {
            return "MyProfile";
        }
    }

    protected override void Configure()
    {
        AutoMapper.Mapper.CreateMap<Audio, customVM>()
            .ForMember(dest => dest.UsersFirstName,
                       opt => opt.MapFrom(src => src.ClientStaff.User.FirstName))
            .ForMember(dest => dest.UsersLastName,
                       opt => opt.MapFrom(src => src.ClientStaff.User.LastName));
    }
}

然后应该在初始化方法中初始化(例如,对于Web项目App_Start

您还应创建单元测试以测试映射是否已正确配置

[TestFixture]
public class MappingTests
{
    [Test]
    public void AutoMapper_Configuration_IsValid()
    {
        Mapper.Initialize(m => m.AddProfile<MyProfile>());
        Mapper.AssertConfigurationIsValid();
    }
}

您的控制器操作将是:

public ActionResult Index()
{
    IEnumerable<Audio> x= db.getAudioFiles();
    IEnumerable<customVM> model =
        Mapper.Map<IEnumerable<Audio>, IEnumerable<customVM>>(x);
    return View(model);
}