【问题标题】:Nested object members null after mapping with Automapper使用 Automapper 映射后嵌套对象成员为空
【发布时间】:2016-07-11 16:05:59
【问题描述】:

我有一个对象

public class Tenant : EntityBase
{
    public virtual string Name { get; set; }
    public virtual string Description { get; set; }
    public virtual string CreatorName { get; set; }
    public virtual TenantState State { get; set; }
    public virtual Address Address { get; set; }

    public virtual IList<TenantActivity> Activities { get; set; }
    public virtual IList<AppUser> Users { get; set; }
    public virtual IList<TenantConfig> TenantConfigs { get; set; }

    ....
}

这样的 DTO:

public class TenantDto
{
    public Guid Id { get; set; }
    public DateTime CDate { get; set; }
    public string CUser { get; set; }
    public string Name { get; set; }
    public string Description { get; set; }
    public string CreatorName { get; set; }
    public TenantState State { get; set; }
    public AddressDto Address { get; set; }
    public List<TenantActivityDto> Activities { get; set; }
    public List<AppUserDto> Users { get; set; }
    public List<TenantConfigDto> TenantConfigs { get; set; }
    ....
}

Address 类是一个 ValueObject,它也有一个 DTO。我使用以下映射(标准,无特殊配置)

public class TenantMapperProfile : Profile
{
    protected override void Configure()
    {
        CreateMap<Tenant, TenantDto>();
        CreateMap<TenantDto, Tenant>();
    }
}

public class AddressMapperProfile : Profile
{
    protected override void Configure()
    {
        CreateMap<Address, AddressDto>();
        CreateMap<AddressDto, Address>();
    }
}

在我的 App.xaml.cs 中有:

        var mapperConfig = new MapperConfiguration(cfg =>
        {
            cfg.AddProfile<TenantMapperProfile>();
            cfg.AddProfile<TenantActivityMapperProfile>();
            cfg.AddProfile<AppUserMapperProfile>();
            cfg.AddProfile<AddressMapperProfile>();
            //cfg.ShouldMapProperty = p => p.SetMethod.IsPrivate || p.GetMethod.IsAssembly;
        });
        Mapper = mapperConfig.CreateMapper();

然后我在这样的服务中调用它:

    public TenantDto CreateTenant(TenantDto tenantDto)
    {
        tenantDto.CreatorName = creatingUserName;
        var tenant = _mapper.Map<Tenant>(tenantDto); 
        tenant = _tenantManagerService.CreateTenant(tenant);//<-- Screenshot made here
        return _mapper.Map<TenantDto>(tenant);
    }

在第一次调用 mapper 后,我制作了调试器窗口的屏幕截图。如您所见,tenantDto 实例包含Address 对象中的数据,但tenant 对象包含正确映射的自己的数据,但嵌套的Address 对象只有空值!我在这里做错了什么??

编辑 - 附加信息

调用mapperConfig.AssertConfigurationIsValid(); 返回一个错误:

无法映射 Bedisoco.BedInventory.Sys.Models.Entities.Role 上的以下属性: 角色 添加自定义映射表达式、忽略、添加自定义解析器或修改目标类型 Bedisoco.BedInventory.Sys.Models.Entities.Role。

Role 对象位于某个列表中的某个位置,我认为List&lt;AppUser&gt; 集合中的User 对象本身包含一个Role 对象列表。它甚至没有完全实现。

假设 Automapper 默默地忽略这些事情我错了吗??

【问题讨论】:

  • 尝试在调用CreateMapper之前添加mapperConfig.AssertConfigurationIsValid();。如果您没有为自动映射器提供足够的信息,它应该会失败。
  • 对于CreateMap&lt;TenantActivity, TenantActivityDto&gt;();等内部实体,您还需要CreateMap
  • 我这样做了,我没有在这里粘贴十几个配置文件类。我已经更新了所有内容,AssertConfigurationIsValid() 不再抛出任何异常。但是我的Address 对象在映射器调用之后仍然只包含 NULL 值。对于不允许 NULL 值的字段,这会导致数据库出现异常。

标签: c# automapper


【解决方案1】:

好的解决了,是我自己的问题。

我的大多数值对象都包含一个包含所有字段的构造函数和一个私有设置器。如果配置正确(cfg.ShouldMapProperty = p =&gt; p.SetMethod.IsPrivate || p.GetMethod.IsAssembly;),Automapper 的私有设置器没有问题。

但 VS 或 ReSharper 建议将 自动属性设置为“仅获取”。这种重构取悦 VS 但不喜欢 Automapper!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-07-20
    • 1970-01-01
    • 2022-01-06
    • 2020-04-03
    • 1970-01-01
    • 2012-02-25
    • 1970-01-01
    • 2020-07-17
    相关资源
    最近更新 更多