/// <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);
        }
Example #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);
        }
Example #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 VisitEntityProjection(EntityProjectionExpression entityProjectionExpression)
        {
            Check.NotNull(entityProjectionExpression, nameof(entityProjectionExpression));

            Visit(entityProjectionExpression.AccessExpression);

            return(entityProjectionExpression);
        }
        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>
        public ObjectArrayProjectionExpression(
            INavigation navigation, Expression accessExpression, EntityProjectionExpression innerProjection = null)
        {
            var targetType = navigation.GetTargetType();

            Type = typeof(IEnumerable <>).MakeGenericType(targetType.ClrType);

            Name = targetType.GetCosmosContainingPropertyName();
            if (Name == null)
            {
                throw new InvalidOperationException(
                          $"Navigation '{navigation.DeclaringEntityType.DisplayName()}.{navigation.Name}' doesn't point to an embedded entity.");
            }

            Navigation       = navigation;
            AccessExpression = accessExpression;
            InnerProjection  = innerProjection ?? new EntityProjectionExpression(
                targetType,
                new RootReferenceExpression(targetType, ""));
        }
        /// <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 ObjectArrayProjectionExpression(
            [NotNull] INavigation navigation,
            [NotNull] Expression accessExpression,
            [CanBeNull] EntityProjectionExpression innerProjection = null)
        {
            var targetType = navigation.TargetEntityType;

            Type = typeof(IEnumerable <>).MakeGenericType(targetType.ClrType);

            Name = targetType.GetContainingPropertyName();
            if (Name == null)
            {
                throw new InvalidOperationException(
                          CosmosStrings.NavigationPropertyIsNotAnEmbeddedEntity(
                              navigation.DeclaringEntityType.DisplayName(), navigation.Name));
            }

            Navigation       = navigation;
            AccessExpression = accessExpression;
            InnerProjection  = innerProjection ?? new EntityProjectionExpression(
                targetType,
                new RootReferenceExpression(targetType, ""));
        }
Example #8
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 abstract Expression VisitEntityProjection(EntityProjectionExpression entityProjectionExpression);
Example #9
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 SelectExpression([NotNull] IEntityType entityType)
 {
     Container      = entityType.GetContainer();
     FromExpression = new RootReferenceExpression(entityType, RootAlias);
     _projectionMapping[new ProjectionMember()] = new EntityProjectionExpression(entityType, FromExpression);
 }
 /// <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 ObjectArrayProjectionExpression Update(Expression accessExpression, EntityProjectionExpression innerProjection)
 => accessExpression != AccessExpression || innerProjection != InnerProjection
         ? new ObjectArrayProjectionExpression(Navigation, accessExpression, innerProjection)
         : this;
Example #11
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(EntityProjectionExpression entityProjection) => AddToProjection(entityProjection, 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 VisitEntityProjection(EntityProjectionExpression entityProjectionExpression)
        {
            Visit(entityProjectionExpression.AccessExpression);

            return(entityProjectionExpression);
        }