AutoMapper 2.1.265中缺少成员

本文关键字:成员 AutoMapper | 更新日期: 2023-09-27 18:26:11

在AutoMapper 2.0中,我使用Profiles来配置映射。我使用SourceMemberNameTransformerDestinationMemberNameTransformer来匹配源和目标属性名称。

在2.1.265中,这些属性不再在配置文件中。有人知道他们为什么被移走吗?但更重要的是,我如何才能复制此功能。

编辑

我一直在看SourceMemberNamingConventionDestinationMemberNamingConvention,但我找不到任何关于它们如何工作的文档。有人有使用自定义INamingConvention的经验吗?

编辑2

源成员是从第三方数据库生成的。通常,它们使用所有小写的列名,单词之间带有下划线。有时他们省略了下划线,有时他们加入了随机大写。

目标成员尽量遵循.NET命名约定。下划线被删除,下划线后面的第一个字符被大写。还对大小写进行了额外的更改,以使成员名称更易于阅读。

为了解决这个问题,我设置了

SourceMemberNameTransformer = name => name.Replace("_", "").ToUpper()
DestinationMemberNameTransformer = name => name.ToUpper()

编辑3

为未来的人们提供更多信息。

我检查了源代码以了解INamingConvention是如何使用的。它的设计方式有点误导。该接口适合作为

public interface INamingConvention
{
    Regex SplittingExpression { get; }
    string SeparatorCharacter { get; }
}

然而,AutoMapper并没有为SourceMemberNamingConventionDestinationMemberNamingConvention 使用完整的界面定义

它获取目标类型的每个成员,并应用DestinationMemberNamingConvention.SplittingExpression。然后,它获取这些匹配部分并使用SourceMemberNamingConvention.SeparatorCharacter调用string.Join。然后,它尝试将源类型成员与目标类型成员相匹配。

这是对is功能的一个非常高级别的概述,而不是试图描述全部功能。这仅仅是为了表明INamingConvention是如何使用的,并且表明SourceMemberNamingConvention.SplittingExpressionDestinationMemberNamingConvention.SeparatorCharacter从未使用过。

如果您无法使用此策略转换目标成员,则必须按照nemesv的答案手动映射属性。

AutoMapper 2.1.265中缺少成员

它将删除此功能,请参阅GitHub。

编辑问题更新后重写:

也许内置的LowerUnderscoreNamingConvention解决了您的问题。我用这个代码进行了测试:

Mapper.Initialize(c => 
    c.SourceMemberNamingConvention = new LowerUnderscoreNamingConvention());
Mapper.CreateMap<Source, Dest>();
var test = Mapper.Map<Dest>(
    new Source() { test_Another_Prop = "test", test_this_prop = "test" });

其中SourceDest:

public class Source
{
    public string test_this_prop { get; set; }
    public string test_Another_Prop { get; set; }
    public string test_wronglynamedprop { get; set; }
}
public class Dest
{
    public string TestThisProp { get; set; }
    public string TestAnotherProp { get; set; } 
    public string TestWronglyNamedProp { get; set; }
}

如果它没有涵盖你的所有案例,你可以检查它是如何在源代码中实现的,并创建你自己的convetion。

编辑:评论后:

当约定不适用时,您可以手动覆盖特殊情况:

Mapper.CreateMap<Source, Dest>()
    .ForMember(d => d.TestWronglyNamedProp, c => c
    .MapFrom(s => s.test_wronglynamedprop));

我在当前版本中看不到其他选项。因为到目前为止,没有什么能取代MemberNameTransformer s。