Beispiel #1
0
        public virtual void AddNavigationBinding(INavigation navigation, EntityShaperExpression entityShaper)
        {
            if (!EntityType.IsAssignableFrom(navigation.DeclaringEntityType) &&
                !navigation.DeclaringEntityType.IsAssignableFrom(EntityType))
            {
                throw new InvalidOperationException(
                          $"Called EntityProjectionExpression.AddNavigationBinding() with incorrect INavigation. " +
                          $"EntityType:{EntityType.DisplayName()}, Property:{navigation.Name}");
            }

            _navigationExpressionsCache[navigation] = entityShaper;
        }
Beispiel #2
0
        /// <summary>
        ///     Adds a navigation binding for this entity projection when the target entity type of the navigation is owned or weak.
        /// </summary>
        /// <param name="navigation"> A navigation to add binding for. </param>
        /// <param name="entityShaper"> An entity shaper expression for the target type. </param>
        public virtual void AddNavigationBinding([NotNull] INavigation navigation, [NotNull] EntityShaperExpression entityShaper)
        {
            Check.NotNull(navigation, nameof(navigation));
            Check.NotNull(entityShaper, nameof(entityShaper));

            if (!EntityType.IsAssignableFrom(navigation.DeclaringEntityType) &&
                !navigation.DeclaringEntityType.IsAssignableFrom(EntityType))
            {
                throw new InvalidOperationException(
                          RelationalStrings.UnableToBindMemberToEntityProjection("Navigation", navigation.Name, EntityType.DisplayName()));
            }

            _ownedNavigationMap[navigation] = entityShaper;
        }
        public virtual void AddNavigationBinding([NotNull] INavigation navigation, [NotNull] EntityShaperExpression entityShaper)
        {
            Check.NotNull(navigation, nameof(navigation));
            Check.NotNull(entityShaper, nameof(entityShaper));

            if (!EntityType.IsAssignableFrom(navigation.DeclaringEntityType) &&
                !navigation.DeclaringEntityType.IsAssignableFrom(EntityType))
            {
                throw new InvalidOperationException(
                          CoreStrings.EntityProjectionExpressionCalledWithIncorrectInterface(
                              "AddNavigationBinding",
                              "INavigation",
                              EntityType.DisplayName(),
                              navigation.Name));
            }

            _navigationExpressionsCache[navigation] = entityShaper;
        }
Beispiel #4
0
            private Expression Expand(Expression source, MemberIdentity member)
            {
                Type convertedType = null;

                if (source is UnaryExpression unaryExpression &&
                    unaryExpression.NodeType == ExpressionType.Convert)
                {
                    source = unaryExpression.Operand;
                    if (unaryExpression.Type != typeof(object))
                    {
                        convertedType = unaryExpression.Type;
                    }
                }

                if (source is EntityShaperExpression entityShaperExpression)
                {
                    var entityType = entityShaperExpression.EntityType;
                    if (convertedType != null)
                    {
                        entityType = entityType.RootType().GetDerivedTypesInclusive()
                                     .FirstOrDefault(et => et.ClrType == convertedType);

                        if (entityType == null)
                        {
                            return(null);
                        }
                    }

                    var navigation = member.MemberInfo != null
                        ? entityType.FindNavigation(member.MemberInfo)
                        : entityType.FindNavigation(member.Name);

                    if (navigation != null &&
                        navigation.ForeignKey.IsOwnership)
                    {
                        if (navigation.IsCollection())
                        {
                            return(CreateShapedQueryExpression(
                                       navigation.GetTargetType(),
                                       _sqlExpressionFactory.Select(navigation.GetTargetType())));
                        }

                        var entityProjectionExpression = (EntityProjectionExpression)
                                                         (entityShaperExpression.ValueBufferExpression is ProjectionBindingExpression projectionBindingExpression
                                ? _selectExpression.GetMappedProjection(projectionBindingExpression.ProjectionMember)
                                : entityShaperExpression.ValueBufferExpression);

                        var innerShaper = entityProjectionExpression.BindNavigation(navigation);
                        if (innerShaper == null)
                        {
                            var targetEntityType      = navigation.GetTargetType();
                            var innerSelectExpression = _sqlExpressionFactory.Select(targetEntityType);
                            var innerShapedQuery      = CreateShapedQueryExpression(targetEntityType, innerSelectExpression);

                            var makeNullable = navigation.ForeignKey.PrincipalKey.Properties
                                               .Concat(navigation.ForeignKey.Properties)
                                               .Select(p => p.ClrType)
                                               .Any(t => t.IsNullableType());

                            var outerKey = CreateKeyAccessExpression(
                                entityShaperExpression, navigation.ForeignKey.PrincipalKey.Properties, makeNullable);
                            var innerKey = CreateKeyAccessExpression(
                                innerShapedQuery.ShaperExpression, navigation.ForeignKey.Properties, makeNullable);

                            var joinPredicate = _sqlTranslator.Translate(Expression.Equal(outerKey, innerKey));
                            _selectExpression.AddLeftJoin(innerSelectExpression, joinPredicate, null);
                            var leftJoinTable = ((LeftJoinExpression)_selectExpression.Tables.Last()).Table;
                            innerShaper = new EntityShaperExpression(targetEntityType,
                                                                     new EntityProjectionExpression(targetEntityType, leftJoinTable, true),
                                                                     true);
                            entityProjectionExpression.AddNavigationBinding(navigation, innerShaper);
                        }

                        return(innerShaper);
                    }
                }

                return(null);
            }