2012-12-19 51 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