/// <summary>
        ///     This is an internal API that supports the Entity Framework Core infrastructure and not subject to
        ///     the same compatibility standards as public APIs. It may be changed or removed without notice in
        ///     any release. You should only use it directly in your code with extreme caution and knowing that
        ///     doing so can result in application failures when updating to a new Entity Framework Core release.
        /// </summary>
        public virtual Expression BindNavigation(INavigation navigation, bool clientEval)
        {
            if (!EntityType.IsAssignableFrom(navigation.DeclaringEntityType) &&
                !navigation.DeclaringEntityType.IsAssignableFrom(EntityType))
            {
                throw new InvalidOperationException(
                          $"Called EntityProjectionExpression.GetNavigation() with incorrect INavigation. EntityType:{EntityType.DisplayName()}, Navigation:{navigation.Name}");
            }

            if (!_navigationExpressionsCache.TryGetValue(navigation, out var expression))
            {
                if (navigation.IsCollection())
                {
                    expression = new ObjectArrayProjectionExpression(navigation, AccessExpression);
                }
                else
                {
                    expression = new EntityProjectionExpression(
                        navigation.GetTargetType(),
                        new ObjectAccessExpression(navigation, AccessExpression));
                }

                _navigationExpressionsCache[navigation] = expression;
            }

            if (!clientEval &&
                expression.Name.Length == 0)
            {
                // Non-persisted navigation can't be translated
                return(null);
            }

            return((Expression)expression);
        }
Exemple #2
0
        /// <summary>
        ///     This is an internal API that supports the Entity Framework Core infrastructure and not subject to
        ///     the same compatibility standards as public APIs. It may be changed or removed without notice in
        ///     any release. You should only use it directly in your code with extreme caution and knowing that
        ///     doing so can result in application failures when updating to a new Entity Framework Core release.
        /// </summary>
        public virtual Expression BindNavigation([NotNull] INavigation navigation, bool clientEval)
        {
            if (!EntityType.IsAssignableFrom(navigation.DeclaringEntityType) &&
                !navigation.DeclaringEntityType.IsAssignableFrom(EntityType))
            {
                throw new InvalidOperationException(
                          CoreStrings.EntityProjectionExpressionCalledWithIncorrectInterface(
                              "GetNavigation", nameof(INavigation), EntityType.DisplayName(), $"Navigation:{navigation.Name}"));
            }

            if (!_navigationExpressionsCache.TryGetValue(navigation, out var expression))
            {
                if (navigation.IsCollection)
                {
                    expression = new ObjectArrayProjectionExpression(navigation, AccessExpression);
                }
                else
                {
                    expression = new EntityProjectionExpression(
                        navigation.TargetEntityType,
                        new ObjectAccessExpression(navigation, AccessExpression));
                }

                _navigationExpressionsCache[navigation] = expression;
            }

            if (!clientEval &&
                expression.Name.Length == 0)
            {
                // Non-persisted navigation can't be translated
                return(null);
            }

            return((Expression)expression);
        }
        /// <summary>
        ///     This is an internal API that supports the Entity Framework Core infrastructure and not subject to
        ///     the same compatibility standards as public APIs. It may be changed or removed without notice in
        ///     any release. You should only use it directly in your code with extreme caution and knowing that
        ///     doing so can result in application failures when updating to a new Entity Framework Core release.
        /// </summary>
        public virtual Expression BindNavigation(INavigation navigation)
        {
            if (!EntityType.IsAssignableFrom(navigation.DeclaringEntityType) &&
                !navigation.DeclaringEntityType.IsAssignableFrom(EntityType))
            {
                throw new InvalidOperationException(
                          $"Called EntityProjectionExpression.GetNavigation() with incorrect INavigation. EntityType:{EntityType.DisplayName()}, Navigation:{navigation.Name}");
            }

            if (!_navigationExpressionsCache.TryGetValue(navigation, out var expression))
            {
                if (navigation.IsCollection())
                {
                    expression = new ObjectArrayProjectionExpression(navigation, AccessExpression);
                }
                else
                {
                    expression = new EntityProjectionExpression(
                        navigation.GetTargetType(),
                        new ObjectAccessExpression(navigation, AccessExpression));
                }

                _navigationExpressionsCache[navigation] = expression;
            }

            return(expression);
        }
Exemple #4
0
        /// <summary>
        ///     This is an internal API that supports the Entity Framework Core infrastructure and not subject to
        ///     the same compatibility standards as public APIs. It may be changed or removed without notice in
        ///     any release. You should only use it directly in your code with extreme caution and knowing that
        ///     doing so can result in application failures when updating to a new Entity Framework Core release.
        /// </summary>
        protected override Expression VisitObjectArrayProjection(ObjectArrayProjectionExpression objectArrayProjectionExpression)
        {
            Check.NotNull(objectArrayProjectionExpression, nameof(objectArrayProjectionExpression));

            _sqlBuilder.Append(objectArrayProjectionExpression);

            return(objectArrayProjectionExpression);
        }
        private Expression TryBindMember(Expression source, MemberIdentity member)
        {
            if (!(source is EntityReferenceExpression entityReferenceExpression))
            {
                return(null);
            }

            var result = member.MemberInfo != null
                ? entityReferenceExpression.ParameterEntity.BindMember(member.MemberInfo, entityReferenceExpression.Type, clientEval : false, out _)
                : entityReferenceExpression.ParameterEntity.BindMember(member.Name, entityReferenceExpression.Type, clientEval: false, out _);

            return(result switch
            {
                EntityProjectionExpression entityProjectionExpression => new EntityReferenceExpression(entityProjectionExpression),
                ObjectArrayProjectionExpression objectArrayProjectionExpression
                => new EntityReferenceExpression(objectArrayProjectionExpression.InnerProjection),
                _ => result
            });
 /// <summary>
 ///     This is an internal API that supports the Entity Framework Core infrastructure and not subject to
 ///     the same compatibility standards as public APIs. It may be changed or removed without notice in
 ///     any release. You should only use it directly in your code with extreme caution and knowing that
 ///     doing so can result in application failures when updating to a new Entity Framework Core release.
 /// </summary>
 protected abstract Expression VisitObjectArrayProjection(ObjectArrayProjectionExpression objectArrayProjectionExpression);
Exemple #7
0
 /// <summary>
 ///     This is an internal API that supports the Entity Framework Core infrastructure and not subject to
 ///     the same compatibility standards as public APIs. It may be changed or removed without notice in
 ///     any release. You should only use it directly in your code with extreme caution and knowing that
 ///     doing so can result in application failures when updating to a new Entity Framework Core release.
 /// </summary>
 public virtual int AddToProjection(ObjectArrayProjectionExpression objectArrayProjection) => AddToProjection(objectArrayProjection, null);
        /// <summary>
        ///     This is an internal API that supports the Entity Framework Core infrastructure and not subject to
        ///     the same compatibility standards as public APIs. It may be changed or removed without notice in
        ///     any release. You should only use it directly in your code with extreme caution and knowing that
        ///     doing so can result in application failures when updating to a new Entity Framework Core release.
        /// </summary>
        protected override Expression VisitObjectArrayProjection(ObjectArrayProjectionExpression objectArrayProjectionExpression)
        {
            _sqlBuilder.Append(objectArrayProjectionExpression);

            return(objectArrayProjectionExpression);
        }