Exemplo n.º 1
0
        private (NavigationExpansionExpression navigationExpression, Expression nullKeyExpression) CreateNullComparisonArguments(
            NavigationBindingExpression navigationBindingExpression,
            NavigationExpansionExpression navigationExpansionExpression)
        {
            var navigationKeyAccessExpression = NavigationExpansionHelpers.CreateKeyAccessExpression(
                navigationBindingExpression,
                new[] { navigationBindingExpression.EntityType.FindPrimaryKey().Properties.First() },
                addNullCheck: true);

            var nullKeyExpression = NavigationExpansionHelpers.CreateNullKeyExpression(
                navigationKeyAccessExpression.Type,
                keyCount: 1);

            var newNavigationExpansionExpressionState = new NavigationExpansionExpressionState(
                navigationExpansionExpression.State.CurrentParameter,
                navigationExpansionExpression.State.SourceMappings,
                Expression.Lambda(navigationKeyAccessExpression, navigationExpansionExpression.State.PendingSelector.Parameters[0]),
                applyPendingSelector: true,
                navigationExpansionExpression.State.PendingOrderings,
                navigationExpansionExpression.State.PendingIncludeChain,
                // we need to remap cardinality reducing operator since it's source type has now changed
                navigationExpansionExpression.State.PendingCardinalityReducingOperator?.GetGenericMethodDefinition().MakeGenericMethod(navigationKeyAccessExpression.Type),
                navigationExpansionExpression.State.PendingTags,
                navigationExpansionExpression.State.CustomRootMappings,
                navigationExpansionExpression.State.MaterializeCollectionNavigation);

            var navigationExpression = new NavigationExpansionExpression(
                navigationExpansionExpression.Operand,
                newNavigationExpansionExpressionState,
                navigationKeyAccessExpression.Type);

            return(navigationExpression, nullKeyExpression);
        }
        private (NavigationExpansionExpression navigationExpression, Expression nullKeyExpression) CreateNullComparisonArguments(
            NavigationBindingExpression navigationBindingExpression,
            NavigationExpansionExpression navigationExpansionExpression)
        {
            var navigationKeyAccessExpression = NavigationExpansionHelpers.CreateKeyAccessExpression(
                navigationBindingExpression,
                navigationBindingExpression.EntityType.FindPrimaryKey().Properties,
                addNullCheck: true);

            var nullKeyExpression = NavigationExpansionHelpers.CreateNullKeyExpression(
                navigationKeyAccessExpression.Type,
                navigationBindingExpression.EntityType.FindPrimaryKey().Properties.Count);

            var newNavigationExpansionExpressionState = new NavigationExpansionExpressionState(
                navigationExpansionExpression.State.CurrentParameter,
                navigationExpansionExpression.State.SourceMappings,
                Expression.Lambda(navigationKeyAccessExpression, navigationExpansionExpression.State.PendingSelector.Parameters[0]),
                applyPendingSelector: true,
                navigationExpansionExpression.State.PendingOrderings,
                navigationExpansionExpression.State.PendingIncludeChain,
                navigationExpansionExpression.State.PendingCardinalityReducingOperator,
                navigationExpansionExpression.State.PendingTags,
                navigationExpansionExpression.State.CustomRootMappings,
                navigationExpansionExpression.State.MaterializeCollectionNavigation);

            var navigationExpression = new NavigationExpansionExpression(
                navigationExpansionExpression.Operand,
                newNavigationExpansionExpressionState,
                navigationKeyAccessExpression.Type);

            return(navigationExpression, nullKeyExpression);
        }
        private NavigationBindingExpression CreateParentBindingExpression(NavigationBindingExpression navigationBindingExpression)
        {
            // TODO: verify this is correct in all cases
            var parentNavigationEntityType = navigationBindingExpression.NavigationTreeNode.Navigation.FindInverse().GetTargetType();
            var parentTreeNode             = navigationBindingExpression.NavigationTreeNode.Parent;

            parentTreeNode.Children.Remove(navigationBindingExpression.NavigationTreeNode);

            return(new NavigationBindingExpression(
                       navigationBindingExpression.RootParameter,
                       parentTreeNode,
                       parentNavigationEntityType,
                       navigationBindingExpression.SourceMapping,
                       parentNavigationEntityType.ClrType));
        }
        public static Expression CreateCollectionNavigationExpression(
            NavigationTreeNode navigationTreeNode, ParameterExpression rootParameter, SourceMapping sourceMapping)
        {
            var collectionEntityType = navigationTreeNode.Navigation.ForeignKey.DeclaringEntityType;
            var entityQueryable      = (Expression)NullAsyncQueryProvider.Instance.CreateEntityQueryableExpression(collectionEntityType.ClrType);

            var outerBinding = new NavigationBindingExpression(
                rootParameter,
                navigationTreeNode.Parent,
                navigationTreeNode.Navigation.DeclaringEntityType,
                sourceMapping,
                navigationTreeNode.Navigation.DeclaringEntityType.ClrType);

            var outerKeyAccess = NavigationExpansionHelpers.CreateKeyAccessExpression(
                outerBinding,
                navigationTreeNode.Navigation.ForeignKey.PrincipalKey.Properties,
                addNullCheck: outerBinding.NavigationTreeNode.Optional);

            var collectionCurrentParameter = Expression.Parameter(collectionEntityType.ClrType, collectionEntityType.ClrType.GenerateParameterName());

            var innerKeyAccess = NavigationExpansionHelpers.CreateKeyAccessExpression(
                collectionCurrentParameter,
                navigationTreeNode.Navigation.ForeignKey.Properties);

            var predicate = Expression.Lambda(
                CreateKeyComparisonExpressionForCollectionNavigationSubquery(
                    outerKeyAccess,
                    innerKeyAccess,
                    outerBinding),
                collectionCurrentParameter);

            var operand = Expression.Call(
                LinqMethodHelpers.QueryableWhereMethodInfo.MakeGenericMethod(collectionEntityType.ClrType),
                entityQueryable,
                predicate);

            var result = NavigationExpansionHelpers.CreateNavigationExpansionRoot(operand, collectionEntityType, navigationTreeNode.Navigation);

            // this is needed for cases like: root.Include(r => r.Collection).ThenInclude(c => c.Reference).Select(r => r.Collection)
            // result should be elements of the collection navigation with their 'Reference' included
            var newSourceMapping = result.State.SourceMappings.Single();

            IncludeHelpers.CopyIncludeInformation(navigationTreeNode, newSourceMapping.NavigationTree, newSourceMapping);

            return(result);
        }