private Expression RewritePropertyAccess( Expression expression, IReadOnlyList <IPropertyBase> properties, IQuerySource querySource) { if (querySource != null && properties.Count > 0 && properties.All(p => p is INavigation) && properties[properties.Count - 1] is INavigation lastNavigation && lastNavigation.IsCollection()) { var qsre = new QuerySourceReferenceExpression(querySource); CollectionNavigationIncludeResultOperators.Add( new IncludeResultOperator(properties.Cast <INavigation>().ToArray(), qsre)); var parameter = Expression.Parameter(querySource.ItemType, querySource.ItemName); var accessorBody = BuildCollectionAccessorExpression(parameter, properties); var emptyCollection = lastNavigation.GetCollectionAccessor().Create(); return(Expression.Call( ProjectCollectionNavigationMethodInfo .MakeGenericMethod(querySource.ItemType, expression.Type), qsre, Expression.Lambda( Expression.Coalesce( accessorBody, Expression.Constant(emptyCollection, accessorBody.Type)), parameter))); } return(expression); }
private Expression RewritePropertyAccess( Expression expression, IReadOnlyList <IPropertyBase> properties, IQuerySource querySource) { if (querySource != null && properties.Count > 0 && properties.All(p => p is INavigation) && properties[properties.Count - 1] is INavigation lastNavigation && lastNavigation.IsCollection()) { // include doesn't handle navigations on derived class, so we can't leverage include pipeline for those cases var expectedCallerType = querySource.ItemType; foreach (var property in properties) { if (expectedCallerType != property.DeclaringType.ClrType) { return(expression); } expectedCallerType = property.ClrType; } var qsre = new QuerySourceReferenceExpression(querySource); CollectionNavigationIncludeResultOperators.Add( new IncludeResultOperator(properties.Cast <INavigation>().ToArray(), qsre)); var parameter = Expression.Parameter(querySource.ItemType, querySource.ItemName); var accessorBody = BuildCollectionAccessorExpression(parameter, properties); var emptyCollection = lastNavigation.GetCollectionAccessor().Create(); return(Expression.Call( ProjectCollectionNavigationMethodInfo .MakeGenericMethod(querySource.ItemType, expression.Type), qsre, Expression.Lambda( Expression.Coalesce( accessorBody, Expression.Constant(emptyCollection, accessorBody.Type)), parameter))); } return(expression); }