【问题标题】:After the Automapper mapping where objects go to null values在对象转到空值的 Automapper 映射之后
【发布时间】:2015-11-20 08:40:21
【问题描述】:
 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

问: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); 行(第二次)时,它会填充AdditionalAddressContactDetail 对象的数据。如何会发生吗?

【问题讨论】:

标签: c# asp.net-mvc automapper asp.net-boilerplate


【解决方案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;}
}

如果您定义从OuterSrcDestination 的默认映射,则TitleInnerSrc 映射到TitleDestination 属性。简单的答案是否定的,因为属性不是根据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));

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

【讨论】:

  • 是的,但是在上述所有情况都相同的情况下,不是吗?为什么它仍然给null
猜你喜欢
  • 2017-09-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-20
相关资源
最近更新 更多