我开始使用MVC和自动映射器并希望得到一些指导。我有一些域模型和视图模型,它们是这些域模型的组合。基本上有4个班级
Transcription
有一个关联的Audio
,由Client Staff
拥有Users
数据库关系图:
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
正在从Transcription
和ClientStaff
获取属性,但如何获取用户的名字和姓氏?或者更确切地说,如何使用自动映射器获得第二级嵌套类属性。或者我是否错误地处理了整个问题?
答案 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);
}