2011-09-29 130 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