簡體   English   中英

AutoMapper Pascal 大小寫 -> 下划線 map 不能反向工作

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM