예제 #1
0
        public virtual void Detects_conflicting_throughput()
        {
            var modelBuilder = CreateConventionalModelBuilder();

            modelBuilder.Entity <Customer>().ToContainer("Orders")
            .HasAutoscaleThroughput(200);
            modelBuilder.Entity <Order>().ToContainer("Orders")
            .HasAutoscaleThroughput(60);

            VerifyError(CosmosStrings.ThroughputMismatch(200, typeof(Customer).Name, typeof(Order).Name, 60, "Orders"), modelBuilder);
        }
예제 #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>
        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));
                    }
                }
            }
        }