0
 public class CreateOrEditOwnerDetailInput : IInputDto
    {
        [Required]
        public OwnerDetailEditDto OwnerDetail { get; set; }
    }

    [AutoMap(typeof(OwnerDetail))]
    public class OwnerDetailEditDto
    {
        public const int MaxLength = 50;
        public const int NotesMaxLength = 300;

        public int? Id { get; set; }

        [Required]
        [MaxLength(MaxLength)]
        public string LastName { get; set; }


        [Required]
        [MaxLength(MaxLength)]
        public string CompanyName { get; set; }

        [Required]
        public OwnerContactDetailDto ContactDetail { get; set; }

        [Required]
        public AdditionalAddressDto AdditionalAddress { get; set; }

    }



 [Table("IpOwnerDetails")]
    public class OwnerDetail : FullAuditedEntity
    {
        public const int MaxLength = 50;
        public const int NotesMaxLength = 300;

        [Required]
        [MaxLength(MaxLength)]
        public virtual string LastName { get; set; }

        [Required]
        [MaxLength(MaxLength)]
        public virtual string CompanyName { get; set; }


        [ForeignKey("AdditionalAddressId")]
        public virtual AdditionalAddress AdditionalAddress { get; set; }
        public virtual int AdditionalAddressId { get; set; }

        [ForeignKey("ContactDetailId")]
        public virtual ContactDetail ContactDetail { get; set; }
        public virtual int ContactDetailId { get; set; }


    }

public class OwnerContactDetailDto : FullAuditedEntityDto
    {
        public const int NumberMaxLength = 20;

        [Required]
        [MaxLength(NumberMaxLength)]
        public string MainPhoneNumber { get; set; }

        [MaxLength(NumberMaxLength)]
        public string HomePhoneNumber { get; set; }

        [Required]
        public ContactDetailType Type { get; set; }
    }

  public class AdditionalAddressDto : FullAuditedEntityDto, IOutputDto
    {
        public const int MaxLength = 50;

        [Required]
        [MaxLength(MaxLength)]
        public string StreetNumber { get; set; }

        [Required]
        public AddressType Type { get; set; }

        [Required]
        public int CityId { get; set; }

        [Required]
        public int StateId { get; set; }


    }

Mapper.CreateMap<AdditionalAddress, AdditionalAddressDto>()
              .ReverseMap()
              .ForMember(additionalAddress => additionalAddress.Id, options => options.Ignore());

            Mapper.CreateMap<ContactDetail, OwnerContactDetailDto>()
              .ReverseMap()
              .ForMember(contactDetail => contactDetail.Id, options => options.Ignore());


 public async Task<int?> EditOwnerDetailAsync(CreateOrEditOwnerDetailInput input)
        {
            var ownerDetail = await _ownerDetailRepository.FirstOrDefaultAsync(p => p.Id == input.OwnerDetail.Id);
            input.OwnerDetail.MapTo(ownerDetail);//after this it goes null
            await _ownerDetailRepository.UpdateAsync(ownerDetail);
            return input.OwnerDetail.Id;

        }

图片网址:http: //imgur.com/a/GRdw6

Q:映射后里面的EditOwnerDetailAsync方法都AdditionalAddressContactDetail去哪里了null。你能告诉我为什么吗?请查看图片了解更多信息。

例外 :

    ERROR 2015-11-20 17:56:18,666 [26   ] lers.Filters.AbpExceptionFilterAttribute - System.Data.Entity.Infrastructure.DbUpdateException: An error occurred while 
updating the entries. See the inner exception for details. ---> 
System.Data.Entity.Core.UpdateException: An error occurred while updating the 
entries. See the inner exception for details. ---> 
System.Data.SqlClient.SqlException: The UPDATE statement conflicted with the 
FOREIGN KEY constraint 
"FK_dbo.IpOwnerDetails_dbo.IpAdditionalAddresses_AdditionalAddressId". The 
conflict occurred in database "IP", table "dbo.IpAdditionalAddresses", column 'Id'.
    The statement has been terminated.

注意:这里奇怪的是,当我将调试指针带回input.OwnerDetail.MapTo(ownerDetail);行(第二次)时,它会填充AdditionalAddress和对象的数据ContactDetail。它怎么会发生?

4

1 回答 1

-1

映射AutoMapper是通过约定或配置完成的。对于嵌套属性,假设您有两个嵌套属性作为地图的来源,例如

public class OuterSrc{
   public string Name {get;set;}
   public InnerSrc Source{get; set;} 
}
public class InnerSrc{
   public string Title{get; set;}
}

对于目的地,您只有一个班级,例如

public class Destination
{
    public string Name{get; set;}
    public string Title{get;set;}
}

如果您定义从OuterSrcto的默认映射DestinationTitle形成InnerSrcmap to 的Title属性Destination。简单的答案是否定的,因为属性不是根据AutoMapper约定命名的。
所以在这种情况下,我有几个选择。首先,我可以更改属性名称以匹配约定,例如

public class Destination{
   public string Name{get;set;} // as earlier
   public string SourceTitle{get;set;} // see the change here. Source is //property in `OuterSrc` and `Title` is property in `InnerSrc`. I just merged //them
}

如果您认为此解决方案不可行,您可以在配置中定义此类映射,例如

AutoMapper.Mapper.CreateMap<OuterSrc, Destination>()
    .ForMember(dest => dest.Title,
               opts => opts.MapFrom(src => src.Source.Title));

通过这样做,您的映射器将知道如何映射您的内部属性。

于 2015-11-20T10:44:59.483 回答