自动化来自不同语言的对象

时间:2017-12-08 13:06:03

标签: c# .net-core automapper-6

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

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

说我有以下

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);

1 个答案:

答案 0 :(得分:3)

是的,你可以这样做。这是代码示例,但请注意它只是示例。它显示了一般方法,但不完整,包含一些不必要的东西,所以要确保你理解那里发生的事情。

首先,自定义映射器:

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}
    }
});