[英]AutoMapper Pascal case -> lower underscore map doesn't work in reverse
我有一個帶有下划線命名約定的 DTO object,我想 map 往返於具有 Pascal 大小寫命名約定的數據庫實體。 我在使用名稱中的數字映射屬性時遇到問題。 這是一個最小的可重現示例:
using AutoMapper;
MapperConfiguration config =
new(cfg =>
{
cfg.SourceMemberNamingConvention = PascalCaseNamingConvention.Instance;
cfg.DestinationMemberNamingConvention = LowerUnderscoreNamingConvention.Instance;
cfg.CreateMap<MyDbEntity, MyDto>().ReverseMap();
});
config.AssertConfigurationIsValid();
IMapper mapper = config.CreateMapper();
// dto.equip_crest_slot_type_1_crest_id_1 = 10
MyDto dto = mapper.Map<MyDto>(new MyDbEntity() { EquipCrestSlotType1CrestId1 = 10 });
// dbEntry.EquipCrestSlotType1CrestId1 = 0
MyDbEntity dbEntry = mapper.Map<MyDbEntity>(dto);
public class MyDto
{
public int equip_crest_slot_type_1_crest_id_1 { get; set; }
}
public class MyDbEntity
{
public int EquipCrestSlotType1CrestId1 { get; set; }
}
從 DTO 創建 DB 實體時,屬性被遺漏了,這很奇怪,因為它以一種方式映射。 我想知道問題是不是ReverseMap()
沒有驗證,如果我做一個實際的反向配置文件,我可以看到:
using AutoMapper;
MapperConfiguration config =
new(cfg =>
{
cfg.SourceMemberNamingConvention = LowerUnderscoreNamingConvention.Instance;
cfg.DestinationMemberNamingConvention = PascalCaseNamingConvention.Instance;
cfg.CreateMap<MyDto, MyDbEntity>();
});
config.AssertConfigurationIsValid();
我確實得到了一個例外
Unhandled exception. AutoMapper.AutoMapperConfigurationException:
Unmapped members were found. Review the types and members below.
Add a custom mapping expression, ignore, add a custom resolver, or modify the source/destination type
For no matching constructor, add a no-arg ctor, add optional arguments, or map all of the constructor parameters
====================
MyDto -> MyDbEntity (Destination member list)
MyDto -> MyDbEntity (Destination member list)
Unmapped properties:
EquipCrestSlotType1CrestId1
我不確定為什么配置文件會以一種方式而不是另一種方式工作,但我認為問題是我誤解了當數字位於屬性名稱中間時 Pascal 大小寫應該如何工作。 lower_underscore 名稱是從客戶端收到的,我無法控制它們,但我可以重命名數據庫實體。
有沒有一種方法可以在不手動分配成員的情況下解決這個問題? 如果重要的話,我在 AutoMapper 12.0.0 上。
如果默認命名約定在您的特定用例中不起作用,您可以隨時替換它。 問題是PascalCaseNamingConvention
將名稱標記為["Equip", "Crest", "Slot", "Type1", "Crest" "Id1"]
,而不是將數字作為單獨的標記,因為LowerUnderscoreNamingConvention
在下划線名稱。
在這種情況下,您可以制作一個與現有的PascalCaseNamingConvention
略有不同的 class,它具有以下源代碼:
public sealed class PascalCaseNamingConvention : INamingConvention
{
public static readonly PascalCaseNamingConvention Instance = new();
public string SeparatorCharacter => "";
public string[] Split(string input)
{
List<string> result = null;
int lower = 0;
for(int index = 1; index < input.Length; index++)
{
if (char.IsUpper(input[index]))
{
result ??= new();
result.Add(input[lower..index]);
lower = index;
}
}
if (result == null)
{
return Array.Empty<string>();
}
result.Add(input[lower..]);
return result.ToArray();
}
}
只需更改Split
function 即可分別標記數字。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.