From 68e2adbeb35cfed7f67a797d5e4a4fccb3a4d7e2 Mon Sep 17 00:00:00 2001 From: BlaiseD Date: Sun, 28 Apr 2019 18:41:30 -0400 Subject: [PATCH] Fix breaking changes from AutoMapper v8.1.0 --- Directory.Build.props | 2 +- ...AutoMapper.Extensions.ExpressionMapping.csproj | 2 +- .../ExpressionMapper.cs | 10 +++++++++- .../Impl/QueryDataSourceInjection.cs | 6 +++--- .../Impl/SourceInjectedQueryProvider.cs | 15 ++++++++++++++- .../ReflectionExtensions.cs | 9 +++++++++ 6 files changed, 37 insertions(+), 7 deletions(-) diff --git a/Directory.Build.props b/Directory.Build.props index b4a3108..5c1070f 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -2,7 +2,7 @@ Jimmy Bogard latest - 2.0.1 + 2.0.2 true $(NoWarn);1701;1702;1591 diff --git a/src/AutoMapper.Extensions.ExpressionMapping/AutoMapper.Extensions.ExpressionMapping.csproj b/src/AutoMapper.Extensions.ExpressionMapping/AutoMapper.Extensions.ExpressionMapping.csproj index 3b677e9..74d1883 100644 --- a/src/AutoMapper.Extensions.ExpressionMapping/AutoMapper.Extensions.ExpressionMapping.csproj +++ b/src/AutoMapper.Extensions.ExpressionMapping/AutoMapper.Extensions.ExpressionMapping.csproj @@ -17,7 +17,7 @@ - + diff --git a/src/AutoMapper.Extensions.ExpressionMapping/ExpressionMapper.cs b/src/AutoMapper.Extensions.ExpressionMapping/ExpressionMapper.cs index 3110252..1a373f2 100644 --- a/src/AutoMapper.Extensions.ExpressionMapping/ExpressionMapper.cs +++ b/src/AutoMapper.Extensions.ExpressionMapping/ExpressionMapper.cs @@ -269,7 +269,15 @@ private PropertyMap PropertyMap(MemberExpression node) ? null : (!node.Member.DeclaringType.IsAssignableFrom(_typeMap.DestinationType) ? null - : _typeMap.GetExistingPropertyMapFor(node.Member))); + : GetExistingPropertyMapFor(node.Member, _typeMap))); + + private PropertyMap GetExistingPropertyMapFor(MemberInfo destinationProperty, TypeMap typeMap) + { + if (!destinationProperty.DeclaringType.IsAssignableFrom(typeMap.DestinationType)) + return null; + + return typeMap.PropertyMaps.FirstOrDefault(pm => pm.DestinationName == destinationProperty.Name); + } private void SetSorceSubTypes(PropertyMap propertyMap) { diff --git a/src/AutoMapper.Extensions.ExpressionMapping/Impl/QueryDataSourceInjection.cs b/src/AutoMapper.Extensions.ExpressionMapping/Impl/QueryDataSourceInjection.cs index e39ab66..4f3aca2 100644 --- a/src/AutoMapper.Extensions.ExpressionMapping/Impl/QueryDataSourceInjection.cs +++ b/src/AutoMapper.Extensions.ExpressionMapping/Impl/QueryDataSourceInjection.cs @@ -72,20 +72,20 @@ public QueryDataSourceInjection(IQueryable dataSource, IMapper mapper) public ISourceInjectedQueryable For(object parameters, params Expression>[] membersToExpand) { _parameters = GetParameters(parameters); - _membersToExpand = ProjectionExpression.GetMemberPaths(membersToExpand); + _membersToExpand = ReflectionExtensions.GetMemberPaths(membersToExpand); return CreateQueryable(); } public ISourceInjectedQueryable For(params Expression>[] membersToExpand) { - _membersToExpand = ProjectionExpression.GetMemberPaths(membersToExpand); + _membersToExpand = ReflectionExtensions.GetMemberPaths(membersToExpand); return CreateQueryable(); } public ISourceInjectedQueryable For(IObjectDictionary parameters, params string[] membersToExpand) { _parameters = parameters; - _membersToExpand = ProjectionExpression.GetMemberPaths(typeof(TDestination), membersToExpand); + _membersToExpand = ReflectionExtensions.GetMemberPaths(typeof(TDestination), membersToExpand); return CreateQueryable(); } diff --git a/src/AutoMapper.Extensions.ExpressionMapping/Impl/SourceInjectedQueryProvider.cs b/src/AutoMapper.Extensions.ExpressionMapping/Impl/SourceInjectedQueryProvider.cs index 7d353fe..1060192 100644 --- a/src/AutoMapper.Extensions.ExpressionMapping/Impl/SourceInjectedQueryProvider.cs +++ b/src/AutoMapper.Extensions.ExpressionMapping/Impl/SourceInjectedQueryProvider.cs @@ -94,7 +94,12 @@ public TResult Execute(Expression expression) var sourceResult = _dataSource.Provider.CreateQuery(sourceExpression); Inspector.SourceResult(sourceExpression, sourceResult); - destResult = new ProjectionExpression((IQueryable)sourceResult, _mapper.ConfigurationProvider.ExpressionBuilder).To(_parameters, _membersToExpand); + var membersToExpand = _membersToExpand.SelectMany(m => m).Distinct().ToArray(); + + var parameters = _parameters ?? new Dictionary(); + var mapExpressions = _mapper.ConfigurationProvider.ExpressionBuilder.GetMapExpression(sourceResult.ElementType, typeof(TDestination), parameters, membersToExpand); + + destResult = (IQueryable)mapExpressions.Aggregate(sourceResult, Select); } // case #2: query is arbitrary ("manual") projection // exaple: users.UseAsDataSource().For().Select(user => user.Age).ToList() @@ -228,6 +233,14 @@ private static Expression Select(Expression source, LambdaExpression lambda) ); } + private static IQueryable Select(IQueryable source, LambdaExpression lambda) => source.Provider.CreateQuery( + Call( + null, + QueryableSelectMethod.MakeGenericMethod(source.ElementType, lambda.ReturnType), + new[] { source.Expression, Expression.Quote(lambda) } + ) + ); + private object InvokeSourceQuery(Type sourceResultType, Expression sourceExpression) { var result = IsProjection(sourceResultType) diff --git a/src/AutoMapper.Extensions.ExpressionMapping/ReflectionExtensions.cs b/src/AutoMapper.Extensions.ExpressionMapping/ReflectionExtensions.cs index f9fb1f5..26e2612 100644 --- a/src/AutoMapper.Extensions.ExpressionMapping/ReflectionExtensions.cs +++ b/src/AutoMapper.Extensions.ExpressionMapping/ReflectionExtensions.cs @@ -1,11 +1,14 @@ using System; using System.Collections.Generic; +using System.Linq; using System.Linq.Expressions; using System.Reflection; using AutoMapper.Internal; namespace AutoMapper { + using MemberPaths = IEnumerable>; + internal static class ReflectionExtensions { public static object GetDefaultValue(this ParameterInfo parameter) @@ -29,6 +32,12 @@ public static object GetMemberValue(this MemberInfo propertyOrField, object targ public static IEnumerable GetMemberPath(Type type, string fullMemberName) => ReflectionHelper.GetMemberPath(type, fullMemberName); + public static MemberPaths GetMemberPaths(Type type, string[] membersToExpand) => + membersToExpand.Select(m => ReflectionHelper.GetMemberPath(type, m)); + + public static MemberPaths GetMemberPaths(Expression>[] membersToExpand) => + membersToExpand.Select(expr => MemberVisitor.GetMemberPath(expr)); + public static MemberInfo GetFieldOrProperty(this LambdaExpression expression) => ReflectionHelper.GetFieldOrProperty(expression);