2012-12-19 50 views
1

我从MVC和自动映射器开始,并希望得到一些指导。我有一些领域模型和视图模型是这些领域模型的组合。基本上有4类MVC和Automapper嵌套的多层次

Transcription具有关联Audio这是由一个Client Staff谁在Users

数据库关系图中的用户ID拥有:EF产生

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

域模型(仅适用字段)

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); 
} 

问题:

AutoMapperTranscriptionClientStaff拿起性质,但我怎么得到用户的名字和姓氏?或者说,概括一下如何通过自动映射器获得第二级嵌套类属性。还是我错误地接近了整个问题?

回答

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)); 
    } 
} 

这应该然后在初始化方法(如App_Start对于Web项目)初始化

您还应该创建一个单元测试来测试映射已经正确配置

[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); 
} 
+0

绝对传奇!感谢这样一个清晰简洁的解释。 Mapper.Map (x)抛出一个无效的参数,所以不认为这会起作用。 – shai

+0

感谢您的更新。我曾经受到过挑战,并且很想知道它是否有效,但还没有机会尝试。 – Mightymuke

+0

请注意,为了安全起见,您可能需要指定您的映射,如下所示:src =>(src.ClientStaff == null || src.ClientStaff.User == null)? string.Empty:src.ClientStaff.User。FirstName' – Mightymuke