AutoMapper unflattening with naming convention 导致空对象
AutoMapper unflattening with naming convention results in null object
我正在使用 AutoMapper 11.0.0 将一个 DTO 映射到另一个 class。
我的目标是将 SupplierDto.CreatedById
和 SupplierDto.CreatedByName
映射到 Supplier.CreatedBy.Id
和 Supplier.CreatedBy.Name
。
阅读 docs,我发现 AutoMapper 有一个不扁平的特性,它使用 PascalCase 命名约定将源映射到目标对象,而不需要逐个映射成员。
问题是我遗漏了一些东西,因为我的 classes 是按照约定命名的,而且我得到的是空对象。
这是我的 classes:
Supplier.cs
public class Supplier
{
public long Id { get; set; }
public string Name { get; set; }
public DateTime CreatedAt { get; set; }
public DateTime? UpdatedAt { get; set; }
public User CreatedBy { get; set; }
public User UpdatedBy { get; set; }
}
User.cs
public class User
{
public long Id { get; set; }
public string Name { get; set; }
public string Email { get; set; }
}
SupplierDto.cs
public class SupplierDto
{
public long Id { get; set; }
public string Name { get; set; }
public string Cnpj { get; set; }
public DateTime CreatedAt { get; set; }
public DateTime? UpdatedAt { get; set; }
public long CreatedById { get; set; }
public string CreatedByName { get; set; }
}
这是我将 SupplierDto 映射到 Supplier 的代码:
var configuration = new MapperConfiguration(cfg =>
{
cfg.CreateMap<SupplierDto, Supplier>();
});
var mapper = new Mapper(configuration);
var dto = new SupplierDto
{
Id = 1,
Name = "Supplier One",
CreatedById = 2,
CreatedByName = "John Doe",
CreatedAt = DateTime.Now,
UpdatedAt = DateTime.Now,
};
var supplier = mapper.Map<Supplier>(dto);
//supplier.CreatedBy is null here
Console.WriteLine(supplier?.CreatedBy?.Name);
我想要达到的结果是这样的:
var supplier = new Supplier {
Id = dto.Id,
Name = dto.Name,
CreatedAt = dto.CreatedAt,
UpdatedAt = dto.UpdatedAt,
CreatedBy = new User
{
Id = dto.CreatedById,
Name = dto.CreatedByName
}
}
AutoMapper 为 Id
、Name
、CreatedAt
和 UpdatedAt
道具创建地图,但不会为 [= 创建新的 User
24=] 道具
我错过了什么?
首先,没有configuration validation的AM很难用。所以这样做:)
然后,正如the docs所说,你需要ReverseMap
来展开。
c.CreateMap<Supplier, SupplierDto>().ForMember(d=>d.Cnpj, o=>o.Ignore()).ReverseMap();
我正在使用 AutoMapper 11.0.0 将一个 DTO 映射到另一个 class。
我的目标是将 SupplierDto.CreatedById
和 SupplierDto.CreatedByName
映射到 Supplier.CreatedBy.Id
和 Supplier.CreatedBy.Name
。
阅读 docs,我发现 AutoMapper 有一个不扁平的特性,它使用 PascalCase 命名约定将源映射到目标对象,而不需要逐个映射成员。
问题是我遗漏了一些东西,因为我的 classes 是按照约定命名的,而且我得到的是空对象。
这是我的 classes:
Supplier.cs
public class Supplier
{
public long Id { get; set; }
public string Name { get; set; }
public DateTime CreatedAt { get; set; }
public DateTime? UpdatedAt { get; set; }
public User CreatedBy { get; set; }
public User UpdatedBy { get; set; }
}
User.cs
public class User
{
public long Id { get; set; }
public string Name { get; set; }
public string Email { get; set; }
}
SupplierDto.cs
public class SupplierDto
{
public long Id { get; set; }
public string Name { get; set; }
public string Cnpj { get; set; }
public DateTime CreatedAt { get; set; }
public DateTime? UpdatedAt { get; set; }
public long CreatedById { get; set; }
public string CreatedByName { get; set; }
}
这是我将 SupplierDto 映射到 Supplier 的代码:
var configuration = new MapperConfiguration(cfg =>
{
cfg.CreateMap<SupplierDto, Supplier>();
});
var mapper = new Mapper(configuration);
var dto = new SupplierDto
{
Id = 1,
Name = "Supplier One",
CreatedById = 2,
CreatedByName = "John Doe",
CreatedAt = DateTime.Now,
UpdatedAt = DateTime.Now,
};
var supplier = mapper.Map<Supplier>(dto);
//supplier.CreatedBy is null here
Console.WriteLine(supplier?.CreatedBy?.Name);
我想要达到的结果是这样的:
var supplier = new Supplier {
Id = dto.Id,
Name = dto.Name,
CreatedAt = dto.CreatedAt,
UpdatedAt = dto.UpdatedAt,
CreatedBy = new User
{
Id = dto.CreatedById,
Name = dto.CreatedByName
}
}
AutoMapper 为 Id
、Name
、CreatedAt
和 UpdatedAt
道具创建地图,但不会为 [= 创建新的 User
24=] 道具
我错过了什么?
首先,没有configuration validation的AM很难用。所以这样做:)
然后,正如the docs所说,你需要ReverseMap
来展开。
c.CreateMap<Supplier, SupplierDto>().ForMember(d=>d.Cnpj, o=>o.Ignore()).ReverseMap();