使用Automapper映射具有相似名称的成员

5
在一个我只能读取的远程数据库中,每个小时的一行有24列。它们的名称是P1、P2、...、P24。
我必须将这些值复制到我的本地数据库中,并将列名命名为H1、H2、...、H24。
如何使用“自动映射器”将远程列映射到本地列?
CreateMap<Data.Context.SomeTableFromRemoteDb, Data.Entity.MyTableInLocaldb>()
                .ForMember(x => x.H1, y => y.MapFrom(z => z.P1))
                .ForMember(x => x.H2, y => y.MapFrom(z => z.P2))
                .ForMember(x => x.H3, y => y.MapFrom(z => z.P3))
                .ForMember(x => x.H4, y => y.MapFrom(z => z.P4))
                .ForMember(x => x.H5, y => y.MapFrom(z => z.P5))
                .ForMember(x => x.H6, y => y.MapFrom(z => z.P6))
                .ForMember(x => x.H7, y => y.MapFrom(z => z.P7))
                .ForMember(x => x.H8, y => y.MapFrom(z => z.P8))
                .ForMember(x => x.H9, y => y.MapFrom(z => z.P9))
                .ForMember(x => x.H10, y => y.MapFrom(z => z.P10))
                 .ForMember(x => x.H11, y => y.MapFrom(z => z.P11))
                 .ForMember(x => x.H12, y => y.MapFrom(z => z.P12))
                 .ForMember(x => x.H13, y => y.MapFrom(z => z.P13))
                 .ForMember(x => x.H14, y => y.MapFrom(z => z.P14))
                 .ForMember(x => x.H15, y => y.MapFrom(z => z.P15))
                 .ForMember(x => x.H16, y => y.MapFrom(z => z.P16))
                 .ForMember(x => x.H17, y => y.MapFrom(z => z.P17))
                 .ForMember(x => x.H18, y => y.MapFrom(z => z.P18))
                 .ForMember(x => x.H19, y => y.MapFrom(z => z.P19))
                 .ForMember(x => x.H20, y => y.MapFrom(z => z.P20))
                 .ForMember(x => x.H21, y => y.MapFrom(z => z.P21))
                 .ForMember(x => x.H22, y => y.MapFrom(z => z.P22))
                 .ForMember(x => x.H23, y => y.MapFrom(z => z.P23))
                 .ForMember(x => x.H24, y => y.MapFrom(z => z.P24));

这是当前的代码。我的要求是能否将它转换为像这样的代码:
CreateMap<Data.Context.SomeTableFromRemoteDb, Data.Entity.MyTableInLocaldb>()
                    .ForMember(x => x.ReplaceMemberName(o=> o, "H", "P"), y => y.MapFrom(z => z.P1))

Automapper有一个名为replacemembername的函数,但它似乎不是我正在寻找的功能。


1
“相似”这个词太主观了。你可能会看到一个重复的模式,但计算机却不会。从它的角度来看,P2和H2之间的一半数据都发生了变化。“carpet”和“puppet”也有一些相似之处,但是由于这种相似,它们之间没有自动连接。除非名称完全相同,否则您需要手动映射属性。 - Flater
1
你现在有任何代码吗?你如何从数据库中获取数据并保存它? - sasha_gud
1
@sasha_gud 获取和保存的过程并不重要,重要的是如何使用Automapper进行映射。 - Doruk
1
@Flater,顺便说一下,如果不是因为Automapper,它可以通过反射或动态完成。 - Doruk
1
@Doruk:并不是说不能使用反射来完成,但我希望你能看到这是一个非常定制化的情况,需要非常定制化的逻辑。通常情况下,一个广泛适用的库不会处理这些事情,因为它提供的是_通用_(虽然理想情况下是可扩展的-这就是你所需要的)功能。在属性名称中带有索引的属性,如P1、P2等,在正确的代码中应该由数组而不是手动编写的属性列表来处理。然后只需要将P数组映射到H数组即可。 - Flater
显示剩余3条评论
1个回答

2
你对于 ReplaceMemberName 的理解几乎正确,但是使用有些不正确。它应该被应用到整个映射器配置中。请参见https://github.com/AutoMapper/AutoMapper/wiki/Configuration#replacing-characters了解详情。
    private static void Main(string[] args)
    {
        var a = new Class1
        {
            a1 = "1",
            a2 = "2",
            a3 = "3",
            a4 = "4",
            a5 = "5"
        };

        Mapper.Initialize(config =>
            {
                config.ReplaceMemberName("a", "b");
                config.CreateMap<Class1, Class2>();
            }
        );

        var b = Mapper.Map<Class1, Class2>(a);
    }

    private class Class1
    {
        public string a1;
        public string a2;
        public string a3;
        public string a4;
        public string a5;
    }

    private class Class2
    {
        public string b1;
        public string b2;
        public string b3;
        public string b4;
        public string b5;
    }

您也可以像这样创建本地映射器:
var config = new MapperConfiguration(c =>
{
    c.ReplaceMemberName("a", "b");
    c.CreateMap<Class1, Class2>();
});

var mapper = config.CreateMapper();

var b = mapper.Map<Class1, Class2>(a);

是的@sasha_gud。我看到了一个关于它的例子,但我不知道为什么这不适用于单个地图。尽管如此,它仍然是我所寻找的最接近的内容,我可能会使用它。 - Doruk
@Doruk,你也可以创建本地映射器来避免更改通用配置。已将相应的代码添加到答案中。 - sasha_gud
我会尝试并回来。 - Doruk
你修改后的代码正是我所需要的。非常感谢。 - Doruk

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接