2

I'm having an issue w/ AutoMapper (3.3.1). I have two queries, one returns a list of an Entity Framework object, the other returns a DataTable. The reason for this is we need different data/results returned from these queries. I'd like to map both of these to the same object model, but I am experiencing strange behavior. Depending on which route I go (see below), I either get an AutoMapper Exception, or I get no values in my list at all. We have multiple objects that do this and would be nice to know what the correct setup is.

Scenario 1

// this function runs on application_start
public static void ConfigureMapping() {
    // ...
    AutoMapper.Mapper.CreateMap<SubObjectClassModel, LUSubObjectClass>();
        AutoMapper.Mapper.CreateMap<LUSubObjectClass, SubObjectClassModel>()
            .ForMember(x => x.ObjectClassCode,
                y => y.MapFrom(x => x.LUObjectClass.Code))
            .ForMember(x => x.ObjectClassGroupCode,
                y => y.MapFrom(x => x.LUObjectClass.GroupCode));

    AutoMapper.Mapper.CreateMap<IDataReader, SubObjectClassModel>();
}

public static List<SubObjectClassModel> Gets()
    {
        LUSubObjectClass subObjectClass = new LUSubObjectClass();
        return Mapper.Map<IDataReader, List<SubObjectClassModel>>(
            subObjectClass.Gets().CreateDataReader()
        );
    }

Running this on the server always gives me this exception:

Missing type map configuration or unsupported mapping. Mapping types: IDataReader -> List`1 System.Data.IDataReader -> System.Collections.Generic.List`1[[BRS.Models.Common.SubObjectClassModel, BRS.Models, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]] Destination path: List`1 Source value: System.Data.DataTableReader

Scenario 2 I tried the solution outlined in this post: http://www.geekytidbits.com/automapper-with-datatables/ but when I run this on the server, I get an empty list back.

With this scenario, I do not create this mapping in my ConfigureMapping fx, just the first:

AutoMapper.Mapper.CreateMap<IDataReader, SubObjectClassModel>();

I've also tried this:

    AutoMapper.Mapper.CreateMap<IDataReader, List<SubObjectClassModel>>();

What is the correct way to go about this?

EDIT Here is some weird behavior. If I do not rebuild my entire project (specifically the project that has the Configure call), I either get the automap exception or no results. If I rebuild everything, I get results. Then when I deploy to the server, I get either the exception or no results.

EDIT 2

Upon further investigation I noticed the following. When I do a run from VS without rebuilding the entire solution and I see no results being returned after the Mapper.Map call, I see all the mappings listed correctly. However, Automappers.Mapper.DataReaderMapper is not listed under AutoMapper.ConfigurationStore.

When results are returned successfully, usually after I rebuild the solution, this mapper is listed.

What would cause that behavior and how can I ensure the DataReaderMapper gets loaded every time?

Khaled
  • 21
  • 2
  • Your question seems to include some code that isn't relevant, while missing some that is. Can you add enough code to reproduce this? If not then inspecting the AutoPapper maps at runtime in the debugger may help. – stuartd May 28 '15 at 21:33
  • Thanks @stuartd. There really isn't much to add code wise that I can think of. I call ConfigureMapping() in global.asax on application start up and then do the gets. That's all there is to it. It behaves the same exact way in my test project so I know it is not related to web. The DataTable returned from my query always looks as I expect it too. How can I investigate AutoMapper maps at runtime? Obviously, the maps were working when I map from EF object to my models. But I had to move away from that due to project requirements. – Khaled May 28 '15 at 22:53
  • Add a breakpoint at `Mapper.Map` and add a watch on Mapper, then drill in to see the mappings – stuartd May 28 '15 at 23:00
  • So here is what happened. On the times that it does not return results, I see all the mappings listed correctly. However, Automappers.Mapper.DataReaderMapper is not listed under AutoMapper.ConfigurationStore. The times it does work fine, this mapper is listed. What would cause that behavior and how can I ensure the DataReaderMapper gets loaded everytime? – Khaled Jun 01 '15 at 18:26
  • Perhaps a known issue? https://github.com/AutoMapper/AutoMapper.Data/issues/7 – Khaled Jun 01 '15 at 18:36
  • Can you set this up in a reproducible way, eg in a unit test? – stuartd Jun 02 '15 at 13:56

1 Answers1

0

I spoke with the AutoMapper team and it basically boiled down to a DLL not being loaded (https://github.com/AutoMapper/AutoMapper.Data/issues/11). The DLL in question is AutoMapper.Net4.dll. I installed AutoMapper as a NuGet Package and don't have any project settings that would not allow this DLL to be loaded.

So I followed the steps in this post: How can I force .NET to use a local copy of an assembly that's in the GAC

  1. Add the missing DLL to the project with the dependency as a Linked File.
  2. On the file properties, Copy To Output Directory, select If Newer.

Now when I create a deployment package and publish it to the server, the DLL is always present in the bin folder and the maps work.

Hope this helps someone. Thanks to everyone for the guidance!

Community
  • 1
  • 1
Khaled
  • 21
  • 2