Ejemplo n.º 1
0
        public virtual async Task Inserting_dependent_without_principal_throws()
        {
            await using (var testDatabase = CreateTestStore())
            {
                using (var context = CreateContext())
                {
                    context.Add(
                        new LicensedOperator
                    {
                        Name        = "Jack Jackson",
                        LicenseType = "Class A CDC",
                        VehicleName = "Fuel transport"
                    });

                    Assert.Equal(
                        CosmosStrings.OrphanedNestedDocumentSensitive(
                            nameof(Operator), nameof(Vehicle), "{VehicleName: Fuel transport}"),
                        Assert.Throws <InvalidOperationException>(() => context.SaveChanges()).Message);
                }
            }
        }
        public async Task Add_update_delete_query_throws_if_no_container()
        {
            await using var testDatabase = CosmosTestStore.CreateInitialized(DatabaseName + "Empty");
            var options = Fixture.CreateOptions(testDatabase);

            var customer = new Customer {
                Id = 42, Name = "Theon"
            };

            using (var context = new CustomerContext(options))
            {
                context.Add(customer);

                Assert.StartsWith(CosmosStrings.CreateItemFailed("NotFound", "Message: {\"Errors\":[\"Resource Not Found\"]}")[..^ 1],
                                  (await Assert.ThrowsAsync <InvalidOperationException>(() => context.SaveChangesAsync())).Message);
            }

            using (var context = new CustomerContext(options))
            {
                context.Add(customer).State = EntityState.Modified;

                Assert.StartsWith(CosmosStrings.ReplaceItemFailed("NotFound", "Message: {\"Errors\":[\"Resource Not Found\"]}")[..^ 1],
                                  (await Assert.ThrowsAsync <InvalidOperationException>(() => context.SaveChangesAsync())).Message);
            }

            using (var context = new CustomerContext(options))
            {
                context.Add(customer).State = EntityState.Deleted;

                Assert.StartsWith(CosmosStrings.DeleteItemFailed("NotFound", "Message: {\"Errors\":[\"Resource Not Found\"]}")[..^ 1],
                                  (await Assert.ThrowsAsync <InvalidOperationException>(() => context.SaveChangesAsync())).Message);
            }

            using (var context = new CustomerContext(options))
            {
                Assert.StartsWith(CosmosStrings.QueryFailed("NotFound", "Message: {\"Errors\":[\"Resource Not Found\"]}")[..^ 1],
                                  (await Assert.ThrowsAsync <InvalidOperationException>(() => context.Set <Customer>().SingleAsync())).Message);
            }
        }
        /// <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, ""));
        }
Ejemplo n.º 4
0
        protected override Expression VisitEntityQueryable([NotNull] Type elementType)
        {
            var entityType = _model.FindEntityType(elementType);

            if (!entityType.IsDocumentRoot())
            {
                throw new InvalidOperationException(
                          CosmosStrings.QueryRootNestedEntityType(entityType.DisplayName(), entityType.FindOwnership().PrincipalEntityType.DisplayName()));
            }

            return(new QueryShaperExpression(
                       QueryModelVisitor.QueryCompilationContext.IsAsyncQuery,
                       new DocumentQueryExpression(
                           QueryModelVisitor.QueryCompilationContext.IsAsyncQuery,
                           entityType.Cosmos().ContainerName,
                           new SelectExpression(entityType, _querySource)),
                       new EntityShaper(entityType,
                                        trackingQuery: QueryModelVisitor.QueryCompilationContext.IsTrackingQuery &&
                                        !entityType.IsQueryType,
                                        useQueryBuffer: QueryModelVisitor.QueryCompilationContext.IsQueryBufferRequired &&
                                        !entityType.IsQueryType,
                                        _entityMaterializerSource)));
        }
        private IUpdateEntry GetRootDocument(InternalEntityEntry entry)
        {
            var stateManager = entry.StateManager;
            var ownership = entry.EntityType.FindOwnership();
            var principal = stateManager.FindPrincipal(entry, ownership);
            if (principal == null)
            {
                if (_sensitiveLoggingEnabled)
                {
                    throw new InvalidOperationException(
                        CosmosStrings.OrphanedNestedDocumentSensitive(
                            entry.EntityType.DisplayName(),
                            ownership.PrincipalEntityType.DisplayName(),
                            entry.BuildCurrentValuesString(entry.EntityType.FindPrimaryKey().Properties)));
                }

                throw new InvalidOperationException(
                    CosmosStrings.OrphanedNestedDocument(
                        entry.EntityType.DisplayName(),
                        ownership.PrincipalEntityType.DisplayName()));
            }

            return principal.EntityType.IsDocumentRoot() ? principal : GetRootDocument(principal);
        }
Ejemplo n.º 6
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 BindProperty([NotNull] IProperty property, bool clientEval)
        {
            if (!EntityType.IsAssignableFrom(property.DeclaringEntityType) &&
                !property.DeclaringEntityType.IsAssignableFrom(EntityType))
            {
                throw new InvalidOperationException(
                          CosmosStrings.UnableToBindMemberToEntityProjection("Property", property.Name, EntityType.DisplayName()));
            }

            if (!_propertyExpressionsMap.TryGetValue(property, out var expression))
            {
                expression = new KeyAccessExpression(property, AccessExpression);
                _propertyExpressionsMap[property] = expression;
            }

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

            return((Expression)expression);
        }
 public string ToQueryString()
 {
     TryGetResourceId(out var resourceId);
     TryGetPartitionId(out var partitionKey);
     return(CosmosStrings.NoReadItemQueryString(resourceId, partitionKey));
 }
Ejemplo n.º 8
0
 private static Exception CreateUnableToDiscriminateException(IEntityType entityType)
 => new InvalidOperationException(CosmosStrings.UnableToDiscriminate(entityType.DisplayName()));
#pragma warning restore EF1001 // Internal EF Core API usage.

        private Exception ThrowUpdateException(CosmosException exception, IUpdateEntry entry)
        {
            var documentSource = GetDocumentSource(entry.EntityType);
            var id             = documentSource.GetId(entry.SharedIdentityEntry ?? entry);

            throw exception.StatusCode switch
                  {
                      HttpStatusCode.PreconditionFailed => new DbUpdateConcurrencyException(CosmosStrings.UpdateConflict(id), exception, new[] { entry }),
                      HttpStatusCode.Conflict => new DbUpdateException(CosmosStrings.UpdateConflict(id), exception, new[] { entry }),
                      _ => Rethrow(exception),
                  };
        }
        /// <summary>
        ///     Validates the compatibility of entity types sharing a given container.
        /// </summary>
        /// <param name="mappedTypes"> The mapped entity types. </param>
        /// <param name="containerName"> The container name. </param>
        /// <param name="logger"> The logger to use. </param>
        protected virtual void ValidateSharedContainerCompatibility(
            [NotNull] IReadOnlyList <IEntityType> mappedTypes,
            [NotNull] string containerName,
            [NotNull] IDiagnosticsLogger <DbLoggerCategory.Model.Validation> logger)
        {
            if (mappedTypes.Count == 1)
            {
                var entityType = mappedTypes[0];
                var partitionKeyPropertyName = entityType.GetCosmosPartitionKeyPropertyName();
                if (partitionKeyPropertyName != null)
                {
                    var nextPartitionKeyProperty = entityType.FindProperty(partitionKeyPropertyName);
                    if (nextPartitionKeyProperty == null)
                    {
                        throw new InvalidOperationException(
                                  CosmosStrings.PartitionKeyMissingProperty(entityType.DisplayName(), partitionKeyPropertyName));
                    }
                }
                return;
            }

            var         discriminatorValues = new Dictionary <object, IEntityType>();
            IProperty   partitionKey        = null;
            IEntityType firstEntityType     = null;

            foreach (var entityType in mappedTypes)
            {
                var partitionKeyPropertyName = entityType.GetCosmosPartitionKeyPropertyName();
                if (partitionKeyPropertyName != null)
                {
                    var nextPartitionKeyProperty = entityType.FindProperty(partitionKeyPropertyName);
                    if (nextPartitionKeyProperty == null)
                    {
                        throw new InvalidOperationException(
                                  CosmosStrings.PartitionKeyMissingProperty(entityType.DisplayName(), partitionKeyPropertyName));
                    }

                    if (partitionKey == null)
                    {
                        if (firstEntityType != null)
                        {
                            throw new InvalidOperationException(CosmosStrings.NoPartitionKey(firstEntityType.DisplayName(), containerName));
                        }
                        partitionKey = nextPartitionKeyProperty;
                    }
                    else if (partitionKey.GetCosmosPropertyName() != nextPartitionKeyProperty.GetCosmosPropertyName())
                    {
                        throw new InvalidOperationException(
                                  CosmosStrings.PartitionKeyStoreNameMismatch(
                                      partitionKey.Name, firstEntityType.DisplayName(), partitionKey.GetCosmosPropertyName(),
                                      nextPartitionKeyProperty.Name, entityType.DisplayName(), nextPartitionKeyProperty.GetCosmosPropertyName()));
                    }
                    else if ((partitionKey.GetTypeMapping().Converter?.ProviderClrType ?? partitionKey.ClrType)
                             != (nextPartitionKeyProperty.GetTypeMapping().Converter?.ProviderClrType ?? nextPartitionKeyProperty.ClrType))
                    {
                        throw new InvalidOperationException(
                                  CosmosStrings.PartitionKeyStoreTypeMismatch(
                                      partitionKey.Name,
                                      firstEntityType.DisplayName(),
                                      (partitionKey.GetTypeMapping().Converter?.ProviderClrType ?? partitionKey.ClrType).ShortDisplayName(),
                                      nextPartitionKeyProperty.Name,
                                      entityType.DisplayName(),
                                      (nextPartitionKeyProperty.GetTypeMapping().Converter?.ProviderClrType ?? nextPartitionKeyProperty.ClrType)
                                      .ShortDisplayName()));
                    }
                }
                else if (partitionKey != null)
                {
                    throw new InvalidOperationException(CosmosStrings.NoPartitionKey(entityType.DisplayName(), containerName));
                }

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

                if (entityType.ClrType?.IsInstantiable() == true)
                {
                    if (entityType.GetDiscriminatorProperty() == null)
                    {
                        throw new InvalidOperationException(
                                  CosmosStrings.NoDiscriminatorProperty(entityType.DisplayName(), containerName));
                    }

                    var discriminatorValue = entityType.GetDiscriminatorValue();
                    if (discriminatorValue == null)
                    {
                        throw new InvalidOperationException(
                                  CosmosStrings.NoDiscriminatorValue(entityType.DisplayName(), containerName));
                    }

                    if (discriminatorValues.TryGetValue(discriminatorValue, out var duplicateEntityType))
                    {
                        throw new InvalidOperationException(
                                  CosmosStrings.DuplicateDiscriminatorValue(
                                      entityType.DisplayName(), discriminatorValue, duplicateEntityType.DisplayName(), containerName));
                    }

                    discriminatorValues[discriminatorValue] = entityType;
                }
            }
        }
Ejemplo n.º 11
0
        private SqlExpression ApplyTypeMappingOnSqlBinary(
            SqlBinaryExpression sqlBinaryExpression,
            CoreTypeMapping typeMapping)
        {
            var left  = sqlBinaryExpression.Left;
            var right = sqlBinaryExpression.Right;

            Type            resultType;
            CoreTypeMapping resultTypeMapping;
            CoreTypeMapping inferredTypeMapping;

            switch (sqlBinaryExpression.OperatorType)
            {
            case ExpressionType.Equal:
            case ExpressionType.GreaterThan:
            case ExpressionType.GreaterThanOrEqual:
            case ExpressionType.LessThan:
            case ExpressionType.LessThanOrEqual:
            case ExpressionType.NotEqual:
            {
                inferredTypeMapping = ExpressionExtensions.InferTypeMapping(left, right)
                                      // We avoid object here since the result does not get typeMapping from outside.
                                      ?? (left.Type != typeof(object)
                            ? _typeMappingSource.FindMapping(left.Type)
                            : _typeMappingSource.FindMapping(right.Type));
                resultType        = typeof(bool);
                resultTypeMapping = _boolTypeMapping;
            }
            break;

            case ExpressionType.AndAlso:
            case ExpressionType.OrElse:
            {
                inferredTypeMapping = _boolTypeMapping;
                resultType          = typeof(bool);
                resultTypeMapping   = _boolTypeMapping;
            }
            break;

            case ExpressionType.Add:
            case ExpressionType.Subtract:
            case ExpressionType.Multiply:
            case ExpressionType.Divide:
            case ExpressionType.Modulo:
            case ExpressionType.LeftShift:
            case ExpressionType.RightShift:
            case ExpressionType.And:
            case ExpressionType.Or:
            {
                inferredTypeMapping = typeMapping ?? ExpressionExtensions.InferTypeMapping(left, right);
                resultType          = inferredTypeMapping?.ClrType ?? left.Type;
                resultTypeMapping   = inferredTypeMapping;
            }
            break;

            default:
                throw new InvalidOperationException(
                          CosmosStrings.UnsupportedOperatorForSqlExpression(
                              sqlBinaryExpression.OperatorType, typeof(SqlBinaryExpression).ShortDisplayName()));
            }

            return(new SqlBinaryExpression(
                       sqlBinaryExpression.OperatorType,
                       ApplyTypeMapping(left, inferredTypeMapping),
                       ApplyTypeMapping(right, inferredTypeMapping),
                       resultType,
                       resultTypeMapping));
        }
Ejemplo n.º 12
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 virtual void ValidateSharedContainerCompatibility(
            [NotNull] IReadOnlyList <IEntityType> mappedTypes,
            [NotNull] string container,
            [NotNull] IDiagnosticsLogger <DbLoggerCategory.Model.Validation> logger)
        {
            var         discriminatorValues = new Dictionary <object, IEntityType>();
            IProperty   partitionKey        = null;
            IEntityType firstEntityType     = null;

            foreach (var entityType in mappedTypes)
            {
                Check.DebugAssert(entityType.IsDocumentRoot(), "Only document roots expected here.");
                var partitionKeyPropertyName = entityType.GetPartitionKeyPropertyName();
                if (partitionKeyPropertyName != null)
                {
                    var nextPartitionKeyProperty = entityType.FindProperty(partitionKeyPropertyName);
                    if (partitionKey == null)
                    {
                        if (firstEntityType != null)
                        {
                            throw new InvalidOperationException(CosmosStrings.NoPartitionKey(firstEntityType.DisplayName(), container));
                        }

                        partitionKey = nextPartitionKeyProperty;
                    }
                    else if (partitionKey.GetJsonPropertyName() != nextPartitionKeyProperty.GetJsonPropertyName())
                    {
                        throw new InvalidOperationException(
                                  CosmosStrings.PartitionKeyStoreNameMismatch(
                                      partitionKey.Name, firstEntityType.DisplayName(), partitionKey.GetJsonPropertyName(),
                                      nextPartitionKeyProperty.Name, entityType.DisplayName(), nextPartitionKeyProperty.GetJsonPropertyName()));
                    }
                }
                else if (partitionKey != null)
                {
                    throw new InvalidOperationException(CosmosStrings.NoPartitionKey(entityType.DisplayName(), container));
                }

                if (mappedTypes.Count == 1)
                {
                    break;
                }

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

                if (entityType.ClrType.IsInstantiable() &&
                    entityType.GetContainingPropertyName() == null)
                {
                    if (entityType.GetDiscriminatorProperty() == null)
                    {
                        throw new InvalidOperationException(
                                  CosmosStrings.NoDiscriminatorProperty(entityType.DisplayName(), container));
                    }

                    var discriminatorValue = entityType.GetDiscriminatorValue();
                    if (discriminatorValue == null)
                    {
                        throw new InvalidOperationException(
                                  CosmosStrings.NoDiscriminatorValue(entityType.DisplayName(), container));
                    }

                    if (discriminatorValues.TryGetValue(discriminatorValue, out var duplicateEntityType))
                    {
                        throw new InvalidOperationException(
                                  CosmosStrings.DuplicateDiscriminatorValue(
                                      entityType.DisplayName(), discriminatorValue, duplicateEntityType.DisplayName(), container));
                    }

                    discriminatorValues[discriminatorValue] = entityType;
                }
            }
        }
Ejemplo n.º 13
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 virtual void ValidateKeys(
            [NotNull] IModel model,
            [NotNull] IDiagnosticsLogger <DbLoggerCategory.Model.Validation> logger)
        {
            foreach (var entityType in model.GetEntityTypes())
            {
                var primaryKey = entityType.FindPrimaryKey();
                if (primaryKey == null ||
                    !entityType.IsDocumentRoot())
                {
                    continue;
                }

                var idProperty = entityType.GetProperties()
                                 .FirstOrDefault(p => p.GetJsonPropertyName() == StoreKeyConvention.IdPropertyJsonName);
                if (idProperty == null)
                {
                    throw new InvalidOperationException(CosmosStrings.NoIdProperty(entityType.DisplayName()));
                }

                var idType = idProperty.GetTypeMapping().Converter?.ProviderClrType
                             ?? idProperty.ClrType;
                if (idType != typeof(string))
                {
                    throw new InvalidOperationException(
                              CosmosStrings.IdNonStringStoreType(
                                  idProperty.Name, entityType.DisplayName(), idType.ShortDisplayName()));
                }

                if (!idProperty.IsKey())
                {
                    throw new InvalidOperationException(CosmosStrings.NoIdKey(entityType.DisplayName(), idProperty.Name));
                }

                var partitionKeyPropertyName = entityType.GetPartitionKeyPropertyName();
                if (partitionKeyPropertyName != null)
                {
                    var partitionKey = entityType.FindProperty(partitionKeyPropertyName);
                    if (partitionKey == null)
                    {
                        throw new InvalidOperationException(
                                  CosmosStrings.PartitionKeyMissingProperty(entityType.DisplayName(), partitionKeyPropertyName));
                    }

                    var partitionKeyType = partitionKey.GetTypeMapping().Converter?.ProviderClrType
                                           ?? partitionKey.ClrType;
                    if (partitionKeyType != typeof(string))
                    {
                        throw new InvalidOperationException(
                                  CosmosStrings.PartitionKeyNonStringStoreType(
                                      partitionKeyPropertyName, entityType.DisplayName(), partitionKeyType.ShortDisplayName()));
                    }

                    if (!partitionKey.GetContainingKeys().Any(k => k.Properties.Contains(idProperty)))
                    {
                        throw new InvalidOperationException(
                                  CosmosStrings.NoPartitionKeyKey(
                                      entityType.DisplayName(), partitionKeyPropertyName, idProperty.Name));
                    }
                }
            }
        }
Ejemplo n.º 14
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 virtual void ValidateSharedContainerCompatibility(
            IReadOnlyList <IEntityType> mappedTypes,
            string container,
            IDiagnosticsLogger <DbLoggerCategory.Model.Validation> logger)
        {
            var                  discriminatorValues = new Dictionary <object, IEntityType>();
            IProperty?           partitionKey        = null;
            int?                 analyticalTTL       = null;
            int?                 defaultTTL          = null;
            ThroughputProperties?throughput          = null;
            IEntityType?         firstEntityType     = null;

            foreach (var entityType in mappedTypes)
            {
                Check.DebugAssert(entityType.IsDocumentRoot(), "Only document roots expected here.");
                var partitionKeyPropertyName = entityType.GetPartitionKeyPropertyName();
                if (partitionKeyPropertyName != null)
                {
                    var nextPartitionKeyProperty = entityType.FindProperty(partitionKeyPropertyName) !;
                    if (partitionKey == null)
                    {
                        if (firstEntityType != null)
                        {
                            throw new InvalidOperationException(CosmosStrings.NoPartitionKey(firstEntityType.DisplayName(), container));
                        }

                        partitionKey = nextPartitionKeyProperty;
                    }
                    else if (partitionKey.GetJsonPropertyName() != nextPartitionKeyProperty.GetJsonPropertyName())
                    {
                        throw new InvalidOperationException(
                                  CosmosStrings.PartitionKeyStoreNameMismatch(
                                      partitionKey.Name, firstEntityType !.DisplayName(), partitionKey.GetJsonPropertyName(),
                                      nextPartitionKeyProperty.Name, entityType.DisplayName(), nextPartitionKeyProperty.GetJsonPropertyName()));
                    }
                }
                else if (partitionKey != null)
                {
                    throw new InvalidOperationException(CosmosStrings.NoPartitionKey(entityType.DisplayName(), container));
                }

                if (mappedTypes.Count == 1)
                {
                    break;
                }

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

                if (entityType.ClrType.IsInstantiable() &&
                    entityType.GetContainingPropertyName() == null)
                {
                    if (entityType.FindDiscriminatorProperty() == null)
                    {
                        throw new InvalidOperationException(
                                  CosmosStrings.NoDiscriminatorProperty(entityType.DisplayName(), container));
                    }

                    var discriminatorValue = entityType.GetDiscriminatorValue();
                    if (discriminatorValue == null)
                    {
                        throw new InvalidOperationException(
                                  CosmosStrings.NoDiscriminatorValue(entityType.DisplayName(), container));
                    }

                    if (discriminatorValues.TryGetValue(discriminatorValue, out var duplicateEntityType))
                    {
                        throw new InvalidOperationException(
                                  CosmosStrings.DuplicateDiscriminatorValue(
                                      entityType.DisplayName(), discriminatorValue, duplicateEntityType.DisplayName(), container));
                    }

                    discriminatorValues[discriminatorValue] = entityType;
                }

                var currentAnalyticalTTL = entityType.GetAnalyticalStoreTimeToLive();
                if (currentAnalyticalTTL != null)
                {
                    if (analyticalTTL == null)
                    {
                        analyticalTTL = currentAnalyticalTTL;
                    }
                    else if (analyticalTTL != currentAnalyticalTTL)
                    {
                        var conflictingEntityType = mappedTypes.First(et => et.GetAnalyticalStoreTimeToLive() != null);
                        throw new InvalidOperationException(
                                  CosmosStrings.AnalyticalTTLMismatch(
                                      analyticalTTL, conflictingEntityType.DisplayName(), entityType.DisplayName(), currentAnalyticalTTL,
                                      container));
                    }
                }

                var currentDefaultTTL = entityType.GetDefaultTimeToLive();
                if (currentDefaultTTL != null)
                {
                    if (defaultTTL == null)
                    {
                        defaultTTL = currentDefaultTTL;
                    }
                    else if (defaultTTL != currentDefaultTTL)
                    {
                        var conflictingEntityType = mappedTypes.First(et => et.GetDefaultTimeToLive() != null);
                        throw new InvalidOperationException(
                                  CosmosStrings.DefaultTTLMismatch(
                                      defaultTTL, conflictingEntityType.DisplayName(), entityType.DisplayName(), currentDefaultTTL, container));
                    }
                }

                var currentThroughput = entityType.GetThroughput();
                if (currentThroughput != null)
                {
                    if (throughput == null)
                    {
                        throughput = currentThroughput;
                    }
                    else if ((throughput.AutoscaleMaxThroughput ?? throughput.Throughput)
                             != (currentThroughput.AutoscaleMaxThroughput ?? currentThroughput.Throughput))
                    {
                        var conflictingEntityType = mappedTypes.First(et => et.GetThroughput() != null);
                        throw new InvalidOperationException(
                                  CosmosStrings.ThroughputMismatch(
                                      throughput.AutoscaleMaxThroughput ?? throughput.Throughput, conflictingEntityType.DisplayName(),
                                      entityType.DisplayName(), currentThroughput.AutoscaleMaxThroughput ?? currentThroughput.Throughput,
                                      container));
                    }
                    else if ((throughput.AutoscaleMaxThroughput == null)
                             != (currentThroughput.AutoscaleMaxThroughput == null))
                    {
                        var conflictingEntityType = mappedTypes.First(et => et.GetThroughput() != null);
                        var autoscaleType         = throughput.AutoscaleMaxThroughput == null
                            ? entityType
                            : conflictingEntityType;
                        var manualType = throughput.AutoscaleMaxThroughput != null
                            ? entityType
                            : conflictingEntityType;

                        throw new InvalidOperationException(
                                  CosmosStrings.ThroughputTypeMismatch(
                                      manualType.DisplayName(), autoscaleType.DisplayName(), container));
                    }
                }
            }
        }
            protected override Expression VisitExtension(Expression extensionExpression)
            {
                Check.NotNull(extensionExpression, nameof(extensionExpression));

                switch (extensionExpression)
                {
                case ProjectionBindingExpression projectionBindingExpression:
                {
                    var projection = GetProjection(projectionBindingExpression);

                    return(CreateGetValueExpression(
                               _jObjectParameter,
                               projection.Alias,
                               projectionBindingExpression.Type, (projection.Expression as SqlExpression)?.TypeMapping));
                }

                case CollectionShaperExpression collectionShaperExpression:
                {
                    ObjectArrayProjectionExpression objectArrayProjection;
                    switch (collectionShaperExpression.Projection)
                    {
                    case ProjectionBindingExpression projectionBindingExpression:
                        var projection = GetProjection(projectionBindingExpression);
                        objectArrayProjection = (ObjectArrayProjectionExpression)projection.Expression;
                        break;

                    case ObjectArrayProjectionExpression objectArrayProjectionExpression:
                        objectArrayProjection = objectArrayProjectionExpression;
                        break;

                    default:
                        throw new InvalidOperationException(CoreStrings.TranslationFailed(extensionExpression.Print()));
                    }

                    var jArray           = _projectionBindings[objectArrayProjection];
                    var jObjectParameter = Expression.Parameter(typeof(JObject), jArray.Name + "Object");
                    var ordinalParameter = Expression.Parameter(typeof(int), jArray.Name + "Ordinal");

                    var accessExpression = objectArrayProjection.InnerProjection.AccessExpression;
                    _projectionBindings[accessExpression] = jObjectParameter;
                    _ownerMappings[accessExpression]      =
                        (objectArrayProjection.Navigation.DeclaringEntityType, objectArrayProjection.AccessExpression);
                    _ordinalParameterBindings[accessExpression] = Expression.Add(
                        ordinalParameter, Expression.Constant(1, typeof(int)));

                    var innerShaper = (BlockExpression)Visit(collectionShaperExpression.InnerShaper);

                    innerShaper = AddIncludes(innerShaper);

                    var entities = Expression.Call(
                        EnumerableMethods.SelectWithOrdinal.MakeGenericMethod(typeof(JObject), innerShaper.Type),
                        Expression.Call(
                            EnumerableMethods.Cast.MakeGenericMethod(typeof(JObject)),
                            jArray),
                        Expression.Lambda(innerShaper, jObjectParameter, ordinalParameter));

                    var navigation = collectionShaperExpression.Navigation;
                    return(Expression.Call(
                               _populateCollectionMethodInfo.MakeGenericMethod(navigation.TargetEntityType.ClrType, navigation.ClrType),
                               Expression.Constant(navigation.GetCollectionAccessor()),
                               entities));
                }

                case IncludeExpression includeExpression:
                {
                    if (!(includeExpression.Navigation is INavigation navigation) ||
                        navigation.IsOnDependent ||
                        navigation.ForeignKey.DeclaringEntityType.IsDocumentRoot())
                    {
                        throw new InvalidOperationException(
                                  CosmosStrings.NonEmbeddedIncludeNotSupported(includeExpression.Navigation));
                    }

                    var isFirstInclude = _pendingIncludes.Count == 0;
                    _pendingIncludes.Add(includeExpression);

                    var jObjectBlock = Visit(includeExpression.EntityExpression) as BlockExpression;

                    if (!isFirstInclude)
                    {
                        return(jObjectBlock);
                    }

                    Check.DebugAssert(jObjectBlock != null, "The first include must end up on a valid shaper block");

                    // These are the expressions added by JObjectInjectingExpressionVisitor
                    var jObjectCondition = (ConditionalExpression)jObjectBlock.Expressions[^ 1];
Ejemplo n.º 16
0
 private static ExpressionType VerifyOperator(ExpressionType operatorType)
 => _allowedOperators.Contains(operatorType)
         ? operatorType
         : throw new InvalidOperationException(
           CosmosStrings.UnsupportedOperatorForSqlExpression(
               operatorType, typeof(SqlBinaryExpression).ShortDisplayName()));
Ejemplo n.º 17
0
 public override void Properties_can_be_made_concurrency_tokens()
 => Assert.Equal(
     CosmosStrings.NonETagConcurrencyToken(nameof(Quarks), "Charm"),
     Assert.Throws <InvalidOperationException>(
         () => base.Properties_can_be_made_concurrency_tokens()).Message);
Ejemplo n.º 18
0
                public bool MoveNext()
                {
                    if (_jsonReader == null)
                    {
                        if (_query == null)
                        {
                            _query = _cosmosClient.CreateQuery(_containerId, _cosmosSqlQuery);
                        }

                        if (!_query.HasMoreResults)
                        {
                            Current = default;
                            return(false);
                        }

                        _responseMessage = _query.ReadNextAsync().GetAwaiter().GetResult();
                        if (!_responseMessage.IsSuccessStatusCode)
                        {
                            throw new InvalidOperationException(CosmosStrings.QueryFailed(_responseMessage.StatusCode, _responseMessage.ErrorMessage));
                        }

                        _responseStream = _responseMessage.Content;
                        _reader         = new StreamReader(_responseStream);
                        _jsonReader     = new JsonTextReader(_reader);

                        while (_jsonReader.Read())
                        {
                            if (_jsonReader.TokenType == JsonToken.StartObject)
                            {
                                while (_jsonReader.Read())
                                {
                                    if (_jsonReader.TokenType == JsonToken.StartArray)
                                    {
                                        goto ObjectFound;
                                    }
                                }
                            }
                        }

                        ObjectFound :;
                    }

                    while (_jsonReader.Read())
                    {
                        if (_jsonReader.TokenType == JsonToken.StartObject)
                        {
                            Current = new JsonSerializer().Deserialize <JObject>(_jsonReader);

                            return(true);
                        }
                    }

                    _jsonReader.Close();
                    _jsonReader = null;
                    _reader.Dispose();
                    _reader = null;
                    _responseStream.Dispose();
                    _responseStream = null;

                    return(MoveNext());
                }