简体   繁体   中英

Automapper base class mapping

For AutoMapper, I've implemented the following which works, but has repeated mapping code:

cfg.CreateMap<RmsOelEntryUnlinkedPersonInputDto, AddNewOELEntryInvolvedEntitiesUnlinkedInvolvedPersonUnlinked>()
    .ForMember(dest => dest.DateOfBirth, opts => opts.MapFrom(src => FormatDateType(src.DateOfBirth)))
    .ForMember(dest => dest.EffectiveFromTime, opts => opts.MapFrom(src => FormatDateTimeType(src.EffectiveFromTime)))
    .ForMember(dest => dest.EffectiveToTime, opts => opts.MapFrom(src => FormatDateTimeType(src.EffectiveToTime)));

cfg.CreateMap<RmsOelEntryUnlinkedAddressInputDto, AddNewOELEntryInvolvedEntitiesUnlinkedInvolvedAddressUnlinked>()
    .ForMember(dest => dest.EffectiveFromTime, opts => opts.MapFrom(src => FormatDateTimeType(src.EffectiveFromTime)))
    .ForMember(dest => dest.EffectiveToTime, opts => opts.MapFrom(src => FormatDateTimeType(src.EffectiveToTime)));

Both RmsOelEntryUnlinkedPersonInputDto and RmsOelEntryUnlinkedAddressInputDto are inherited from RmsOelEntryInvolvedEntityBaseDto and this base class has the properties EffectiveFromTime and EffectiveToTime .

I don't want the to have to repeatedly map EffectiveFromTime and EffectiveToTime as seen above.

However, AddNewOELEntryInvolvedEntitiesUnlinkedInvolvedPersonUnlinked and AddNewOELEntryInvolvedEntitiesUnlinkedInvolvedAddressUnlinked are autogenerated and don't have a base class. Therefore I don't see how I can use AutoMapper's "Include" mapping option.

How do I optimise this to remove the repeated mapping?

I had similar situation and have resorted to helper Extension methods. I customized for your case :

internal static class CommonMapperExtensions
{
     internal static IMappingExpression<TSource, TDestination> MapCommonFields<TSource, TDestination>(this IMappingExpression<TSource, TDestination> m)
         where TSource : RmsOelEntryInvolvedEntityBaseDto
         where TDestination : IEffective
     {
         return m
            .ForMember(dest => dest.EffectiveFromTime, opts => opts.MapFrom(src => FormatDateTimeType(src.EffectiveFromTime)))
            .ForMember(dest => dest.EffectiveToTime, opts => opts.MapFrom(src => FormatDateTimeType(src.EffectiveToTime)));                
     }
}

Then configuration would look like this :

cfg.CreateMap<RmsOelEntryUnlinkedPersonInputDto, AddNewOELEntryInvolvedEntitiesUnlinkedInvolvedPersonUnlinked>()
    .MapCommonFields()
    .ForMember(dest => dest.DateOfBirth, opts => opts.MapFrom(src => FormatDateType(src.DateOfBirth)));

cfg.CreateMap<RmsOelEntryUnlinkedAddressInputDto, AddNewOELEntryInvolvedEntitiesUnlinkedInvolvedAddressUnlinked>()
    .MapCommonFields();

If AddNewOELEntryInvolvedEntitiesUnlinkedInvolvedAddressUnlinked and AddNewOELEntryInvolvedEntitiesUnlinkedInvolvedPersonUnlinked are autogenerated I would assume they are partial.

Then you could make common interface for those classes :

public interface IEffective 
{
     DateTime EffectiveFromTime {get; set;}
     DateTime EffectiveToTime {get; set;}
}

public partial AddNewOELEntryInvolvedEntitiesUnlinkedInvolvedAddressUnlinked
    : IEffective { }

public partial AddNewOELEntryInvolvedEntitiesUnlinkedInvolvedPersonUnlinked
    : IEffective { }
public class TBaseModel
{
    public void ConfigureMapFrom(IMappingExpression<TEntity, TBaseModel> mapping)
    {
        // ... mappings
    }
}

public class TModel : TBaseModel
{
    public void ConfigureMapFrom(IMappingExpression<TEntity, TModel> mapping)
    {
        mapping.IncludeBase<TEntity, TBaseModel>();

        // ... other mappings
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM