Closed k290 closed 2 years ago
This looks to be an issue with Equivalency expression when mapping types using AM.Collection.EF or EFCore.
It looks at DestinationType
to find Primary Key members and used maps with said key properties to generate an equivalency expression. This expression fails with these errors when no matches are present.
This is so when you want to update an existing item, or compare classes to each other you know which ones already exist in the database and can be updated, and which should be removed or deleted. You can also add EquivalencyExpression()
after create map to make your own comparison expression and that will fix the error message as well.
Source/destination types
Mapping configuration
Version: 10.1.1
Expected behavior
When mapping lists, exception is not thrown if the DestinationType happens to be added as a DbSet to the DbContext
Actual behavior
Exception is thrown
Steps to reproduce
Consider the following code mapping a List from the SourceType to the DestinationType:
This works perfectly fine.
However when DestinationType is added to a DataContext as such
Then automapper fails with the below exception and stack trace when doing the mapping: Object reference not set to an instance of an object. Stack Trace: at AutoMapper.Collection.Runtime.GeneratePropertyMapsFeature.<>c.b5_0(PropertyMap pm)
at System.Linq.Enumerable.Any[TSource](IEnumerableb 1(IGeneratePropertyMaps x)
at System.Linq.Enumerable.SelectIListIterator
1 source, Func
2 predicate) at AutoMapper.Collection.Runtime.GeneratePropertyMapsFeature.CreateEquivalentExpression(IEnumerable`1 propertyMaps) at AutoMapper.Collection.Runtime.GeneratePropertyMapsFeature.<>c__DisplayClass3_0.2.MoveNext() at System.Linq.Enumerable.TryGetFirst[TSource](IEnumerable
1 source, Func2 predicate, Boolean& found) at System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable
1 source, Func2 predicate) at AutoMapper.Collection.Runtime.GeneratePropertyMapsFeature.<>c__DisplayClass3_0.<Get>b__0(TypePair _) at System.Collections.Concurrent.ConcurrentDictionary
2.GetOrAdd(TKey key, Func2 valueFactory) at AutoMapper.Collection.Runtime.GeneratePropertyMapsFeature.Get(TypeMap typeMap) at AutoMapper.EquivalencyExpression.EquivalentExpressions.GetEquivalentExpression(IConfigurationProvider configurationProvider, TypeMap typeMap) at AutoMapper.EquivalencyExpression.EquivalentExpressions.GetEquivalentExpression(IConfigurationObjectMapper mapper, Type sourceType, Type destinationType) at AutoMapper.Mappers.EquivalentExpressionAddRemoveCollectionMapper.MapExpression(IConfigurationProvider configurationProvider, ProfileMap profileMap, IMemberMap memberMap, Expression sourceExpression, Expression destExpression, Expression contextExpression) at AutoMapper.MapperConfiguration.GenerateObjectMapperExpression(MapRequest mapRequest, IObjectMapper mapperToUse) at AutoMapper.MapperConfiguration.BuildExecutionPlan(MapRequest mapRequest) at AutoMapper.MapperConfiguration.CompileExecutionPlan(MapRequest mapRequest) at AutoMapper.Internal.LockingConcurrentDictionary
2.<>c__DisplayClass2_1.<.ctor>b__1() at System.Lazy1.ViaFactory(LazyThreadSafetyMode mode) at System.Lazy
1.ExecutionAndPublication(LazyHelper executionAndPublication, Boolean useDefaultConstructor) at System.Lazy1.CreateValue() at System.Lazy
1.get_Value() at AutoMapper.Internal.LockingConcurrentDictionary`2.GetOrAdd(TKey key) at AutoMapper.MapperConfiguration.GetExecutionPlan(MapRequest mapRequest) at AutoMapper.MapperConfiguration.GetExecutionPlan[TSource,TDestination](MapRequest mapRequest) at AutoMapper.Mapper.MapCore[TSource,TDestination](TSource source, TDestination destination, ResolutionContext context, Type sourceType, Type destinationType, IMemberMap memberMap) at AutoMapper.Mapper.Map[TSource,TDestination](TSource source, TDestination destination) at AutoMapper.Mapper.Map[TSource,TDestination](TSource source)Note that if the DbSet is removed from the dbContext the mapping works perfectly fine. Also note that this is only an issue when mapping lists