internal static ICollection <FilteredIncludeExpression> MapFilteredIncludes <TModel, TData>(this ICollection <FilteredIncludeExpression> filteredIncludes, IMapper mapper) { if (filteredIncludes == null) { return(null); } LambdaExpression GetFilter(LambdaExpression nextFilter, Type sourceMemberType, Type destMemberType) { if (nextFilter == null) { return(null); } return((LambdaExpression)mapper.Map ( nextFilter, typeof(Expression <>).MakeGenericType ( new Type[] { sourceMemberType.IsList() ? typeof(Func <,>).MakeGenericType(new Type[] { sourceMemberType.GetUnderlyingElementType(), typeof(bool) }) : typeof(Func <,>).MakeGenericType(new Type[] { sourceMemberType, typeof(bool) }) } ), typeof(Expression <>).MakeGenericType ( new Type[] { destMemberType.IsList() ? typeof(Func <,>).MakeGenericType(new Type[] { destMemberType.GetUnderlyingElementType(), typeof(bool) }) : typeof(Func <,>).MakeGenericType(new Type[] { destMemberType, typeof(bool) }) } ) )); } return(filteredIncludes.Aggregate(new List <FilteredIncludeExpression>(), (list, next) => { if (next.Include == null) { throw new ArgumentNullException("FilteredIncludeExpression.Include is required."); } //Map with member converted to object LambdaExpression mappedInclude = mapper.MapExpressionAsInclude <Expression <Func <TData, object> > >(next.Include); //Get the member expression as an "uncast" member expression MemberExpression mappedIncludeMemberExpression = mappedInclude.Body.GetMemberExpression(); //Uncast expression's member type for the selected member Type destMemberType = mappedIncludeMemberExpression.GetMemberType(); //Uncast expression's member type for the source's selected member Type sourceMemberType = next.Include.Body.GetMemberExpression().GetMemberType(); //Recreate the lanbda expression so it is strongly typed. For collections the type must be IEnumerable<TProperty>. //EntityEntry<T>.Collection expects an expression selector of type Expression<Func<T, IEnumerable<TProperty>>> mappedInclude = Expression.Lambda ( typeof(Func <,>).MakeGenericType ( new Type[] { typeof(TData), destMemberType.IsList() ? typeof(IEnumerable <>).MakeGenericType(new Type[] { destMemberType.GetUnderlyingElementType() }) : destMemberType } ), mappedIncludeMemberExpression, mappedInclude.Parameters[0] ); list.Add ( new FilteredIncludeExpression { Include = mappedInclude, Filter = GetFilter(next.Filter, sourceMemberType, destMemberType), FilteredIncludes = next.FilteredIncludes == null ? null : (ICollection <FilteredIncludeExpression>)MAP_FILTERED_INCLUDES_METHOD.GetMethod().MakeGenericMethod ( /*TModel*/ sourceMemberType.IsList() ? sourceMemberType.GetUnderlyingElementType() : sourceMemberType, //should not be a literal type. A flattened include should not have child includes /*TData*/ destMemberType.IsList() ? destMemberType.GetUnderlyingElementType() : destMemberType ).Invoke(null, new object[] { next.FilteredIncludes, mapper }) } ); return list; })); }