来自不同语言的自动映射对象

Automap objects from different language

我正在尝试找到一种方法来拥有可以在列表中完全不同的名称之间进行映射的映射配置。

我们的数据库是荷兰语的,脚手架工具(如 scaffold-dbcontext)保留 DTO 的 table 名称。在我们的数据库相关层之外,我们更喜欢英语名词。

假设我有以下内容

Afdeling
  Id: int
  TypeKode: string
  Werkenemers: Persoon[]

Department
  Id: int
  TypeCode: string
  Employees: Person[]

鉴于我知道下面的单词映射

Afdeling    Department
Kode        Code
Werkenemers Employees
Persoon     Person

然后是否可以将 AutoMapper 配置为能够这样映射:

Department department = Mapper.Map<Afdeling, Department>(afdeling);

是的,你可以做到。这是代码示例,但请注意它只是 示例。它显示了一般方法,但并不完整并且包含一些不必要的内容,因此请确保您了解那里发生了什么。

首先,自定义映射器:

class DictionaryMapper : ISourceToDestinationNameMapper {
    public Dictionary<string, string> Map { get; set; }
    public MemberInfo GetMatchingMemberInfo(IGetTypeInfoMembers getTypeInfoMembers, TypeDetails typeInfo, Type destType, Type destMemberType, string nameToSearch) {
        if (Map == null || !Map.ContainsKey(nameToSearch))
            return null;
        // map properties using Map dictionary
        return typeInfo.DestinationMemberNames
            .Where(c => c.Member.Name == Map[nameToSearch])
            .Select(c => c.Member)
            .FirstOrDefault();
    }
}

然后

var langMappings = new Dictionary<string, string>();
// note that it's better to use two dictionaries - one for type names
// and another for properties
langMappings.Add("Afdeling", "Department");            
langMappings.Add("TypeKode", "TypeCode");            
langMappings.Add("Werkenemers", "Employees");            
langMappings.Add("Persoon", "Person");
// create reverse map
foreach (var kv in langMappings.ToArray())
    langMappings.Add(kv.Value, kv.Key);

var config = new MapperConfiguration(cfg => {
    // this will allow mapping type with name from dictionary key above
    // to another type indicated with name indicated by value
    // so, Afdeling to Department
    cfg.AddConditionalObjectMapper().Where((s, d) => langMappings.ContainsKey(s.Name) && langMappings[s.Name] == d.Name);
    cfg.AddMemberConfiguration()
    // this is default automapper configuration,
    // see http://docs.automapper.org/en/stable/Conventions.html
    .AddMember<NameSplitMember>()
    .AddName<PrePostfixName>(_ => _.AddStrings(p => p.Prefixes, "Get"))
    // and this one is our custom one
    .AddName<DictionaryMapper>(_ => _.Map = langMappings);
});
var mapper = config.CreateMapper();
var result = mapper.Map<Afdeling, Department>(new Afdeling
{
    Id = 1,
    TypeKode = "code",
    Werkenemers = new[] {
        new Persoon() {Id = 2}
    }
});