Search code examples
c#automapperllblgen

automapper unexpected fields c#


I am trying to map a simple model to an entity but get a list of unmapped items that I was not expecting, it fails at the validation line of AutomapperCfg:

SaveImportRunDetailsModel -> ImportRunDetailEntity (Destination member list) FCSD.Models.SaveImportRunDetailsModel -> LLBLGEN.EntityClasses.ImportRunDetailEntity (Destination member list)

Unmapped properties:

Id
ConcurrencyPredicateFactoryToUse
AuthorizerToUse
AuditorToUse
Validator
ActiveContext
IsNew
Fields
IsDirty

These look like system generated items, is there a way to dismiss them?

AutomapperCfg.cs is

using AutoMapper;
using FCSD.Models;
using LLBLGEN.EntityClasses;

namespace FCSD.Automapper
{
    public class AutomapperCfg : IAutomapperCfg
    {
        public void Configure()
        {
            Mapper.Initialize(cfg =>
            {
                cfg.CreateMap<CategoryEntity, Category>(MemberList.Destination);
                cfg.CreateMap<EnglishPartInfoEntity, EnglishPartModel>(MemberList.Destination);
                cfg.CreateMap<ImageEntity, Image>(MemberList.Destination);
                cfg.CreateMap<ImportRunDetailEntity, ImportRunDetailModel>(MemberList.Destination);
                cfg.CreateMap<ModelExportBaseEntity, Model>(MemberList.Destination).ReverseMap();
                cfg.CreateMap<PartEntity, Part>(MemberList.Destination);

                cfg.CreateMap<SaveImportRunDetailsModel, ImportRunDetailEntity>(MemberList.Destination);
            });

            Mapper.AssertConfigurationIsValid();
        }
    }
}

The SaveImportRunDetailsModel is

using System;

namespace FCSD.Models
{
    public class SaveImportRunDetailsModel
    {
        public string PHCreationDate { get; set; }
        public DateTime RunTimestamp { get; set; }
    }
}

lastly, the ImportRunDetailEntity is a bit long (over 400 lines) and is autogenerated c# from LLBLGen Pro.


Solution

  • What's Happening

    AutoMapper will throw an exception if your destination type contains any properties it cannot match to a property on the source, if it has not been told explicitly how to fill that property.

    How to fix it

    If you do not wish AutoMapper to fill a property, you're expected to use this extension method on the CreateMap<TSource, TDest>()'s return, for each field to ignore:

     .ForMember(dest => dest.Id, opt => opt.Ignore())
     .ForMember(dest => dest.ConcurrencyPredicateFactoryToUse, opt => opt.Ignore())
     .ForMember(dest => dest.AuthorizerToUse, opt => opt.Ignore());
    

    and so on.

    But that sucks...

    Obviously this is a bit of a drag and takes the "auto" right out of AutoMapper, so you may want to consider something like this AutoMapper: "Ignore the rest"? - which will automatically ignore all destination members which are non-existing on the source object.

    One more thing

    You might want to write a unit test which configures a Mapper instance with all your Mappings, then call Mapper.AssertConfigurationIsValid() to discover any issues at Test Time rather than at Run Time, as by default, AutoMapper will not bother validating a mapping until the first time you attempt to use it.