2011-09-29 125 views
1

我在嘗試使用複雜類型時遇到問題AutoMapper複雜類型的AutoMapper

我有兩個對象,一個域和ViewModel utlize在我的視圖;

視圖模型

public class RegisterCoupleModel 
{ 
    [Required(ErrorMessage = "campo obrigatório")] 
    [Display(Name = "Primeiro nome", Order = 0, GroupName = "Noivo")] 
    [StringLength(60)] 
    public string FistNameGroom 
    { 
     get; 
     set; 
    } 

    [Required(ErrorMessage = "campo obrigatório")] 
    [Display(Name = "Último nome", Order = 1, GroupName = "Noivo")] 
    [StringLength(60)] 
    public string LastNameGroom 
    { 
     get; 
     set; 
    } 

    [Required(ErrorMessage = "campo obrigatório")] 
    [RegularExpression(@"^[\w-\.][email protected]([\w-]+\.)+[\w-]{2,4}$", ErrorMessage = "Formato de email inválido.")] 
    [DataType(DataType.EmailAddress)] 
    [Remote("IsEmailAvailable", "Validation", "", ErrorMessage = "este email já está sendo usado por outro usuário.")] 
    [Display(Name = "Email", Order = 2, GroupName = "Noivo")] 
    [StringLength(180)] 
    public string EmailGroom 
    { 
     get; 
     set; 
    } 

    [Required(ErrorMessage = "campo obrigatório")] 
    [Display(Name = "Primeiro nome", Order = 0, GroupName = "Noiva")] 
    [StringLength(60)] 
    public string FistNameBride 
    { 
     get; 
     set; 
    } 

    [Required(ErrorMessage = "campo obrigatório")] 
    [Display(Name = "Último nome", Order = 1, GroupName = "Noiva")] 
    [StringLength(60)] 
    public string LastNameBride 
    { 
     get; 
     set; 
    } 

    [Required(ErrorMessage = "campo obrigatório")] 
    [RegularExpression(@"^[\w-\.][email protected]([\w-]+\.)+[\w-]{2,4}$", ErrorMessage = "Formato de email inválido.")] 
    [DataType(DataType.EmailAddress)] 
    [Remote("IsEmailAvailable", "Validation", "", ErrorMessage = "este email já está sendo usado por outro usuário.")] 
    [Display(Name = "Email", Order = 2, GroupName = "Noiva")] 
    [StringLength(180)] 
    public string EmailBride 
    { 
     get; 
     set; 
    } 

    [Required(ErrorMessage = "campo obrigatório")] 
    [Display(Name = "Url")] 
    [RegularExpression(@"^[a-zA-Z0-9_\-\.\+]{5,22}$", ErrorMessage = "Chave inválida")] 
    [StringLength(22, MinimumLength = 5, ErrorMessage = "A chave deve ter entre {0} e {1} caracteres.")] 
    [Remote("IsKeywordAvaliable", "Validation")] 
    public string UrlKeyword 
    { 
     get; 
     set; 
    } 

    [Display(Name = "Voce é humano?")] 
    [UIHint("ReCaptcha")] 
    public string ReCaptcha 
    { 
     get; 
     set; 
    } 
} 

域對象

public class Couple 
{ 
    [Key] 
    public Guid Id { get; set; } 
    public string UrlKeyword { get; set; } 
    public virtual Partner Groom { get; set; } 
    public virtual Partner Bride { get; set; } 
    public DateTime Marriage { get; set; } 
    public DateTime Dating { get; set; } 
    public DateTime Engagement { get; set; } 
    public virtual ICollection<User> Users { get; set; } 
} 

如果你看看你會看到我的對象Couple域有屬性有BrideGroom這實際上是同一類型

如何映射我的域對象CoupleRegisterCoupleModel

這裏我做到了儘可能:

在設置automapper試着這樣做:

CreateMap<RegisterCoupleModel, Couple>() 
    .ForMember(dest => dest.Bride.User.FirstName, opt => opt.MapFrom(source => source.FistNameBride)) 
    .ForMember(dest => dest.Bride.User.LastName, opt => opt.MapFrom(source => source.LastNameBride)) 
    .ForMember(dest => dest.Bride.User.Email, opt => opt.MapFrom(source => source.EmailBride)) 
    .ForMember(dest => dest.Groom.User.FirstName, opt => opt.MapFrom(source => source.FistNameGroom)) 
    .ForMember(dest => dest.Groom.User.LastName, opt => opt.MapFrom(source => source.LastNameGroom)) 
    .ForMember(dest => dest.Groom.User.Email, opt => opt.MapFrom(source => source.EmailGroom)); 

但顯示以下錯誤:

表達「DEST => dest.Bride.User.FirstName'必須解析爲 頂級成員。參數名稱:lambda表達式

我知道這需要嘗試使用映射屬性與嵌套類型的行爲。

但我怎麼能映射到RegisterCoupleModelCouple兩個屬性BrideGroom是同一類型?

我發現question here on StackOverflow看起來像這樣,但它幫助了我。

回答

2

什麼,我會做的是封裝屬性爲FirstNameBrideLastNameBrideEmailBrideFirstNameGroomLastNameGroomEmailGroom到嵌套視圖模型類型,比方說PersonDetails

public class PersonDetails 
{ 
    public string FirstName { get; set; } 
    public string LastName { get; set; } 
    public string Email { get; set; } 
} 

並相應地更新您的父虛擬機:

public class RegisterCoupleModel 
{ 
    public PersonDetails GroomDetails { get; set; } 
    public PersonDetails BrideDetails { get; set; } 
} 

然後,您可以提供從PersonDetailsUser(或任何類型的Groom。用戶):

Mapper.CreateMap<PersonDetails,User>(); 

注意我怎麼有這麼露骨屬性映射 - >因爲場在源和目的地的名稱相同,因此無需顯式映射。請儘可能地嘗試並做到這一點。代碼越少 - >代碼越好。

那麼除了上述映射,只需做到這一點:

Mapper.CreateMap<RegisterCoupleModel, Couple>(); 

而且AutoMapper會看到RegisterCoupleModel有兩個PersonDetails對象,看到它已經有一個映射定義,然後自動使用它。

這應該工作(我以前做過)。

您不應該總是使用平面視圖模型,在必要時將它們嵌套(例如重新使用字段)。

+0

但是屬性如何? 如果封裝這些字段,新娘和新郎的屬性設置是相同的。 因此,例如,我無法更改顯示文本或GrupName顯示屬性。 – ridermansb

+1

@Riderman - 使用一些OO技巧,例如製作PersonDetails抽象,然後爲BrideDetails和GroomDetails創建派生類。在基礎中設置公共屬性,然後覆蓋不同的屬性。 – RPM1984

+0

我使用助手:'@ Html.EditorForModel()'生成表單,但它不生成嵌套類型。 如何封裝這三個屬性,並使幫助器繼續在窗體中顯示它們? – ridermansb