We are using Entity Framework Core, with a set of Entities that all share a base class.
public class EntityBase { ... }
public class FirstEntityChild : EntityBase { ... }
public class SecondEntityChild : EntityBase { ... }
We use this so we can query for either a FirstEntityChild or SecondEntityChild without needing to know which one at compile time.
To provide the data to our view, we have view models.
public class FirstEntityChildViewModel { ... }
public class SecondEntityChildViewModel { ... }
We're hoping to use AutoMapper's ProjectTo to map the query results from our database entity to a view model. We have mapping profiles set up from FirstEntityChild to FirstEntityChildViewModel and from SecondEntityChild to SecondEntityChildViewModel. We have no maps from EntityBase.
We're currently attempting to accomplish this through type inference with an extension method:
public static IQueryable<TDestination> ProjectTo<TSource, TDestination>(
this IQueryable<TSource> query,
TSource sourceTypeInstance,
TDestination destinationTypeInstance,
IConfigurationProvider configuration)
{
return query.ProjectTo<TDestination>(configuration);
}
And we're using that as follows, given that sourceType is either FirstEntityChild or SecondEntityChild, and targetType is either FirstEntityChildViewModel or SecondEntityChildViewModel, and both are known only at runtime:
var sourceInstance = Activator.CreateInstance(sourceType);
var targetInstance = Activator.CreateInstance(targetType);
var results = await query
.ProjectTo(sourceInstance, targetInstance, mapper.ConfigurationProvider)
.ToListAsync();
The issue we're facing happens inside our ProjectTo extension. When I debug and stop on that line, sourceTypeInstance and destinationTypeInstance appear in the debugger to be FirstEntityChild and FirstEntityChildViewModel respectively. But when the line executes, AutoMapper attempts to map from EntityBase to object, which we don't have a mapping profile for (and which I don't think would even be possible):
InvalidOperationException: Missing map from EntityBase to System.Object. Create using Mapper.CreateMap.
Is it possible to indicate the actual, derived type AutoMapper should be using? Or are we just bumping up against the limitations of generics at this point?
FirstEntityChildtoFirstEntityChildViewModel? or do you only have maps fromEntityBaseto something? - Vidmantas BlazeviciusFirstEntityChildtoFirstEntityChildViewModelandSecondEntityChildtoSecondEntityChildViewModel. No maps fromEntityBaseto anything else. Thank you for pointing this out, I've edited the question to reflect this. - Jimmydefault(TSource)todefault(TDestinationwould be better? Why issourceInstanceeven needed here since you intend source to come from EF? - Vidmantas Blazeviciusmapper.ConfigurationProvidermaybe doesn't hold the config for your maps. - Vidmantas BlazeviciusMapon an enumerated list of our entities works just fine. Besides, the error message we get indicates that AutoMapper isn't using our mapping profiles, as it is mapping from and to the wrong types. - Jimmy