5

In a remote db, which I can only read, there are 24 columns in a row for each hour of day. Their names go as P1, P2, ..., P24.

I must copy the values to my own db, which I named column names as H1, H2, ..., H24.

How can I use auto mapper to map remote columns to locals ?

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

This is the current code. What I ask is can we convert it to something like this:

CreateMap<Data.Context.SomeTableFromRemoteDb, Data.Entity.MyTableInLocaldb>()
                    .ForMember(x => x.ReplaceMemberName(o=> o, "H", "P"), y => y.MapFrom(z => z.P1))

Automapper has a function with name replacemembername but It does not seem to be what I'm seeking.

Doruk
  • 884
  • 9
  • 25
  • 1
    "similar" is too subjective. You see a recurring pattern, but a computer does not. From its point of view, half of the data in the name changes between P2 and H2. "carpet" and "puppet" are halfway similar too; but there's no automatic connection between them because of that. Unless the names are _identical_, you will need to manually map the properties. – Flater Jun 01 '17 at 07:34
  • 1
    Do you have any code so far? How do you obtain data from the DB and save it? – sasha_gud Jun 01 '17 at 07:35
  • @Flatter, you are completely right. I am now doing it manually. But consider having, say 1000 properties. Doing it manually would be absurd. Automapper must have some function to match patterns. Maybe it does, and this is what i am asking. – Doruk Jun 01 '17 at 07:38
  • 1
    @sasha_gud the process of obtaining and saving is irrelevant. What matters is how to map them using automapper. – Doruk Jun 01 '17 at 07:39
  • Are DB columns stored in object fields with corresponding names? – sasha_gud Jun 01 '17 at 07:40
  • 1
    @Flater, btw it could be done with reflection or dynamic if it was not for automapper. – Doruk Jun 01 '17 at 07:51
  • 1
    @Doruk: Not saying it can't be done using reflection, but I hope you see that this is a very custom case with very custom logic. A widely applicable library usually doesn't handle these things, as it provides _generalized_ (though ideally extendable - which is what you need) functionalities. Properties with an index in their name, like P1,P2,... should (in proper code) be handled by an array, not a manually written list of properties. Then it is only a matter of mapping the P array to the H array. – Flater Jun 01 '17 at 08:00
  • @Flater, thanks for responses and effort. – Doruk Jun 01 '17 at 08:02

1 Answers1

2

You were alomst right about ReplaceMemberName, but used it a bit incorrectly. It should be applied to entire mapper configuration. See https://github.com/AutoMapper/AutoMapper/wiki/Configuration#replacing-characters for details.

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

You can also create local mapper like this:

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
  • 1,635
  • 13
  • 18