简体   繁体   中英

Automapper Project From Interface to Concrete Class

I'm trying to perform a mapping between an EF domain object to a DTO object using the Automapper 'Project' method, but am having problems when trying to project from an interface to a concrete class. My EF domain object implements an interface that I use commonly with my lookup tables:

public interface ILookupItem
{
    int Id { get; set; }
    string Name { get; set; }
}

and here's an example of my domain object:

public partial class ReportType : ILookupItem
{
    public int Id { get; set; }
    public string Name { get; set; }
}

In my app, I'm using a DTO object which exactly matches the domain object interface:

public class LookupItemModel
{
    public static void CreateMapping(IConfiguration configuration)
    {
        configuration.CreateMap<ILookupItem, LookupItemModel>();
    }

    public int Id { get; set; }
    public string Name { get; set; }
}

I then perform my database query with a call such as:

return DbContext.Query<ReportType>().Project().To<LookupItemModel>();

however on this call Automapper gives an error about missing a required mapping to perform the function:

Missing map from ReportType to LookupItemModel. Create using Mapper.CreateMap<ReportType, LookupItemModel>.

I would have assumed that the mapping could be performed from the interface since all it should need to know are the properties which to pull data for (Id & Name). Am I missing something to be able to perform this projection without creating maps for each concrete implementation of my interface?

Thanks!

I asked in a comment but haven't had a response yet but I'm fairly sure this is your problem so I'm going to go ahead and make it an answer.

You're creating the mapping between ILookupItem and LookupItemModel but you aren't ever calling the method that creates the map - LookupItemModel.CreateMapping() .

Before you do the mapping you need to call this method:

LookupItemModel.CreateMapping(your IConfiguration);
return DbContext.Query<ReportType>().Project().To<LookupItemModel>();

That said, instead of setting up your mapping logic inside your models, I would create an AutoMapper configuration class that sets up all your maps. Something like:

public class AutoMapperConfig {
    public static CreateMaps() {
        CreateLookupItemMaps();
    }

    public static CreateLookupItemMaps() {
        Mapper.CreateMap<ILookupItem, LookupItemModel>();
    }
}

Or a cleaner approach would be to use AutoMapper Profiles

And then call AutomapperConfig.CreateMaps() during your app startup and you should be good.

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