-
Notifications
You must be signed in to change notification settings - Fork 2.4k
Closed
Description
Source/destination types
public class Foo
{
public string Value { get; set; }
}
public class Bar
{
public ImmutableArray<byte> Value { get; set; }
}Mapping configuration
new MapperConfiguration(cfg =>
cfg.CreateMap<Foo, Bar>()
.ForMember(
bar => bar.Value,
m => m.MapFrom((foo, bar) => Convert.FromBase64String(foo.Value).ToImmutableArray())));Version: 10.1.1 and 11.0.0
Expected behavior
bar.Value should be assigned the ImmutableArray<byte> created by the MapFrom delegate.
Actual behavior
On v10.1.1 an exception was thrown while building the configuration:
The binary operator Equal is not defined for the types 'System.Collections.Immutable.ImmutableArray`1[System.Byte]' and 'System.Object'.
at System.Linq.Expressions.Expression.GetEqualityComparisonOperator(ExpressionType binaryType, String opName, Expression left, Expression right, Boolean liftToNull)
at System.Linq.Expressions.Expression.Equal(Expression left, Expression right, Boolean liftToNull, MethodInfo method)
at System.Linq.Expressions.Expression.Equal(Expression left, Expression right)
at AutoMapper.Internal.CollectionMapperExpressionFactory.<MapCollectionExpression>g__UseDestinationValue|1_0(<>c__DisplayClass1_0& )
at AutoMapper.Internal.CollectionMapperExpressionFactory.MapCollectionExpression(IConfigurationProvider configurationProvider, ProfileMap profileMap, IMemberMap memberMap, Expression sourceExpression, Expression destExpression, Expression contextExpression, Type ifInterfaceType, MapItem mapItem)
at AutoMapper.Mappers.CollectionMapper.MapExpression(IConfigurationProvider configurationProvider, ProfileMap profileMap, IMemberMap memberMap, Expression sourceExpression, Expression destExpression, Expression contextExpression)
at AutoMapper.Execution.ExpressionBuilder.ObjectMapperExpression(IConfigurationProvider configurationProvider, ProfileMap profileMap, TypePair typePair, Expression sourceParameter, Expression contextParameter, IMemberMap propertyMap, Expression destinationParameter)
at AutoMapper.Execution.ExpressionBuilder.MapExpression(IConfigurationProvider configurationProvider, ProfileMap profileMap, TypePair typePair, Expression sourceParameter, Expression contextParameter, IMemberMap propertyMap, Expression destinationParameter)
at AutoMapper.Execution.TypeMapPlanBuilder.CreatePropertyMapFunc(IMemberMap memberMap, Expression destination, MemberInfo destinationMember)
at AutoMapper.Execution.TypeMapPlanBuilder.CreateAssignmentFunc(Expression destinationFunc)
at AutoMapper.Execution.TypeMapPlanBuilder.CreateMapperLambda(HashSet`1 typeMapsPath)
at AutoMapper.TypeMap.CreateMapperLambda(IConfigurationProvider configurationProvider, HashSet`1 typeMapsPath)
at AutoMapper.TypeMap.Seal(IConfigurationProvider configurationProvider)
at AutoMapper.MapperConfiguration.Seal()
at AutoMapper.MapperConfiguration..ctor(MapperConfigurationExpression configurationExpression)
at AutoMapper.MapperConfiguration..ctor(Action`1 configure)
at UserQuery.Main(), line 3
I tried v11.0.0 and it failed similarly, but with a different exception:
InvalidOperationException: Coalesce used with type that cannot be null
at System.Linq.Expressions.Expression.ValidateCoalesceArgTypes(Type left, Type right)
at System.Linq.Expressions.Expression.Coalesce(Expression left, Expression right, LambdaExpression conversion)
at System.Linq.Expressions.Expression.Coalesce(Expression left, Expression right)
at AutoMapper.Internal.Mappers.CollectionMapper.<MapExpression>g__UseDestinationValue|2_3(<>c__DisplayClass2_1& )
at AutoMapper.Internal.Mappers.CollectionMapper.<MapExpression>g__MapCollectionCore|2_1(Expression destExpression, <>c__DisplayClass2_0& )
at AutoMapper.Internal.Mappers.CollectionMapper.MapExpression(IGlobalConfiguration configurationProvider, ProfileMap profileMap, MemberMap memberMap, Expression sourceExpression, Expression destExpression)
at AutoMapper.Execution.ExpressionBuilder.MapExpression(IGlobalConfiguration configurationProvider, ProfileMap profileMap, TypePair typePair, Expression sourceParameter, MemberMap propertyMap, Expression destinationParameter)
at AutoMapper.Execution.TypeMapPlanBuilder.MapMember(MemberMap memberMap, Expression destinationMemberValue, ParameterExpression resolvedValue)
at AutoMapper.Execution.TypeMapPlanBuilder.CreatePropertyMapFunc(MemberMap memberMap, Expression destination, MemberInfo destinationMember)
at AutoMapper.Execution.TypeMapPlanBuilder.CreateAssignmentFunc(Expression createDestination)
at AutoMapper.Execution.TypeMapPlanBuilder.CreateMapperLambda(HashSet`1 typeMapsPath)
at AutoMapper.TypeMap.CreateMapperLambda(IGlobalConfiguration configurationProvider, HashSet`1 typeMapsPath)
at AutoMapper.TypeMap.Seal(IGlobalConfiguration configurationProvider, HashSet`1 typeMapsPath)
at AutoMapper.MapperConfiguration.Seal()
at AutoMapper.MapperConfiguration..ctor(MapperConfigurationExpression configurationExpression)
at AutoMapper.MapperConfiguration..ctor(Action`1 configure)
at UserQuery.Main(), line 3
Steps to reproduce
Running the above code is all that is needed. Here is a minimal LinqPad query that repros the issue:
<Query Kind="Program">
<NuGetReference Version="10.1.1">AutoMapper</NuGetReference>
<Namespace>AutoMapper</Namespace>
<Namespace>System.Collections.Immutable</Namespace>
<Namespace>System.Threading.Tasks</Namespace>
</Query>
void Main()
{
new MapperConfiguration(cfg =>
cfg.CreateMap<Foo, Bar>()
.ForMember(
bar => bar.Value,
m => m.MapFrom((foo, bar) => Convert.FromBase64String(foo.Value).ToImmutableArray())));
}
// You can define other methods, fields, classes and namespaces here
public class Foo
{
public string Value { get; set; }
}
public class Bar
{
public ImmutableArray<byte> Value { get; set; }
}Notes
- In my use-case I know that the source
stringvalue will not benull. - I can work around this by ignoring the member in configuration and doing the mapping in the
AfterMapaction.
Metadata
Metadata
Assignees
Labels
No labels