From e542e35b2cdf03120cc4585d93f3c7163fd8d007 Mon Sep 17 00:00:00 2001 From: Andriy Svyryd Date: Mon, 8 Aug 2022 20:58:41 -0700 Subject: [PATCH] Add IConventionEntityTypeBuilder.GetTargetEntityTypeBuilder Make all IConvention* extension methods that set annotations return the value from the annotation that was set Part of #22414 --- .../Extensions/CosmosEntityTypeExtensions.cs | 42 +++---- .../Extensions/CosmosModelExtensions.cs | 8 +- .../Extensions/CosmosPropertyExtensions.cs | 8 +- ...osmosInversePropertyAttributeConvention.cs | 9 +- .../RelationalEntityTypeExtensions.cs | 41 ++---- .../RelationalForeignKeyExtensions.cs | 8 +- .../Extensions/RelationalIndexExtensions.cs | 16 +-- .../Extensions/RelationalKeyExtensions.cs | 8 +- .../Extensions/RelationalModelExtensions.cs | 23 ++-- .../RelationalNavigationExtensions.cs | 8 +- .../RelationalPropertyExtensions.cs | 94 +++++--------- .../Metadata/Internal/StoredProcedure.cs | 46 +++---- .../SqlServerEntityTypeExtensions.cs | 50 +++----- .../Extensions/SqlServerIndexExtensions.cs | 30 ++--- .../Extensions/SqlServerKeyExtensions.cs | 9 +- .../Extensions/SqlServerModelExtensions.cs | 96 ++++++-------- .../Extensions/SqlServerPropertyExtensions.cs | 118 +++++++----------- .../Extensions/SqlitePropertyExtensions.cs | 4 +- .../Builders/IConventionEntityTypeBuilder.cs | 16 +++ ...tionDispatcher.ImmediateConventionScope.cs | 2 +- .../InversePropertyAttributeConvention.cs | 8 +- .../RelationshipDiscoveryConvention.cs | 10 +- .../Metadata/IConventionNavigationBase.cs | 5 +- .../Internal/InternalEntityTypeBuilder.cs | 30 ++++- .../CosmosApiConsistencyTest.cs | 8 ++ .../SqliteApiConsistencyTest.cs | 19 +++ test/EFCore.Tests/ApiConsistencyTest.cs | 1 + 27 files changed, 305 insertions(+), 412 deletions(-) diff --git a/src/EFCore.Cosmos/Extensions/CosmosEntityTypeExtensions.cs b/src/EFCore.Cosmos/Extensions/CosmosEntityTypeExtensions.cs index d31b1d090dd..bec05146d3a 100644 --- a/src/EFCore.Cosmos/Extensions/CosmosEntityTypeExtensions.cs +++ b/src/EFCore.Cosmos/Extensions/CosmosEntityTypeExtensions.cs @@ -48,14 +48,14 @@ public static void SetContainer(this IMutableEntityType entityType, string? name /// The entity type to set the container name for. /// The name to set. /// Indicates whether the configuration was specified using a data annotation. - public static void SetContainer( + public static string? SetContainer( this IConventionEntityType entityType, string? name, bool fromDataAnnotation = false) - => entityType.SetOrRemoveAnnotation( + => (string?)entityType.SetOrRemoveAnnotation( CosmosAnnotationNames.ContainerName, Check.NullButNotEmpty(name, nameof(name)), - fromDataAnnotation); + fromDataAnnotation)?.Value; /// /// Gets the for the container to which the entity type is mapped. @@ -96,14 +96,14 @@ public static void SetContainingPropertyName(this IMutableEntityType entityType, /// The entity type to set the containing property name for. /// The name to set. /// Indicates whether the configuration was specified using a data annotation. - public static void SetContainingPropertyName( + public static string? SetContainingPropertyName( this IConventionEntityType entityType, string? name, bool fromDataAnnotation = false) - => entityType.SetOrRemoveAnnotation( + => (string?)entityType.SetOrRemoveAnnotation( CosmosAnnotationNames.PropertyName, Check.NullButNotEmpty(name, nameof(name)), - fromDataAnnotation); + fromDataAnnotation)?.Value; /// /// Gets the for the parent property to which the entity type is mapped. @@ -138,14 +138,14 @@ public static void SetPartitionKeyPropertyName(this IMutableEntityType entityTyp /// The entity type to set the partition key property name for. /// The name to set. /// Indicates whether the configuration was specified using a data annotation. - public static void SetPartitionKeyPropertyName( + public static string? SetPartitionKeyPropertyName( this IConventionEntityType entityType, string? name, bool fromDataAnnotation = false) - => entityType.SetOrRemoveAnnotation( + => (string?)entityType.SetOrRemoveAnnotation( CosmosAnnotationNames.PartitionKeyName, Check.NullButNotEmpty(name, nameof(name)), - fromDataAnnotation); + fromDataAnnotation)?.Value; /// /// Gets the for the property that is used to store the partition key. @@ -232,14 +232,14 @@ public static void SetETagPropertyName(this IMutableEntityType entityType, strin /// The entity type to set the ETag property name for. /// The name to set. /// Indicates whether the configuration was specified using a data annotation. - public static void SetETagPropertyName( + public static string? SetETagPropertyName( this IConventionEntityType entityType, string? name, bool fromDataAnnotation = false) - => entityType.SetOrRemoveAnnotation( + => (string?)entityType.SetOrRemoveAnnotation( CosmosAnnotationNames.ETagName, Check.NullButNotEmpty(name, nameof(name)), - fromDataAnnotation); + fromDataAnnotation)?.Value; /// /// Gets the for the property that is used to store the etag. @@ -296,14 +296,14 @@ public static void SetAnalyticalStoreTimeToLive(this IMutableEntityType entityTy /// The entity type. /// The time to live to set. /// Indicates whether the configuration was specified using a data annotation. - public static void SetAnalyticalStoreTimeToLive( + public static int? SetAnalyticalStoreTimeToLive( this IConventionEntityType entityType, int? seconds, bool fromDataAnnotation = false) - => entityType.SetOrRemoveAnnotation( + => (int?)entityType.SetOrRemoveAnnotation( CosmosAnnotationNames.AnalyticalStoreTimeToLive, seconds, - fromDataAnnotation); + fromDataAnnotation)?.Value; /// /// Gets the for the time to live for analytical store in seconds at container scope. @@ -340,14 +340,14 @@ public static void SetDefaultTimeToLive(this IMutableEntityType entityType, int? /// The entity type. /// The time to live to set. /// Indicates whether the configuration was specified using a data annotation. - public static void SetDefaultTimeToLive( + public static int? SetDefaultTimeToLive( this IConventionEntityType entityType, int? seconds, bool fromDataAnnotation = false) - => entityType.SetOrRemoveAnnotation( + => (int?)entityType.SetOrRemoveAnnotation( CosmosAnnotationNames.DefaultTimeToLive, seconds, - fromDataAnnotation); + fromDataAnnotation)?.Value; /// /// Gets the for the default time to live in seconds at container scope. @@ -390,19 +390,19 @@ public static void SetThroughput(this IMutableEntityType entityType, int? throug /// The throughput to set. /// Whether autoscale is enabled. /// Indicates whether the configuration was specified using a data annotation. - public static void SetThroughput( + public static int? SetThroughput( this IConventionEntityType entityType, int? throughput, bool? autoscale, bool fromDataAnnotation = false) - => entityType.SetOrRemoveAnnotation( + => (int?)entityType.SetOrRemoveAnnotation( CosmosAnnotationNames.Throughput, throughput == null || autoscale == null ? null : autoscale.Value ? ThroughputProperties.CreateAutoscaleThroughput(throughput.Value) : ThroughputProperties.CreateManualThroughput(throughput.Value), - fromDataAnnotation); + fromDataAnnotation)?.Value; /// /// Gets the for the provisioned throughput at container scope. diff --git a/src/EFCore.Cosmos/Extensions/CosmosModelExtensions.cs b/src/EFCore.Cosmos/Extensions/CosmosModelExtensions.cs index 7f4b8b2c7e5..ad47182bbab 100644 --- a/src/EFCore.Cosmos/Extensions/CosmosModelExtensions.cs +++ b/src/EFCore.Cosmos/Extensions/CosmosModelExtensions.cs @@ -44,14 +44,10 @@ public static void SetDefaultContainer(this IMutableModel model, string? name) this IConventionModel model, string? name, bool fromDataAnnotation = false) - { - model.SetOrRemoveAnnotation( + => (string?)model.SetOrRemoveAnnotation( CosmosAnnotationNames.ContainerName, Check.NullButNotEmpty(name, nameof(name)), - fromDataAnnotation); - - return name; - } + fromDataAnnotation)?.Value; /// /// Returns the configuration source for the default container name. diff --git a/src/EFCore.Cosmos/Extensions/CosmosPropertyExtensions.cs b/src/EFCore.Cosmos/Extensions/CosmosPropertyExtensions.cs index a3f9dccd932..e3a33708622 100644 --- a/src/EFCore.Cosmos/Extensions/CosmosPropertyExtensions.cs +++ b/src/EFCore.Cosmos/Extensions/CosmosPropertyExtensions.cs @@ -66,14 +66,10 @@ public static void SetJsonPropertyName(this IMutableProperty property, string? n this IConventionProperty property, string? name, bool fromDataAnnotation = false) - { - property.SetOrRemoveAnnotation( + => (string?)property.SetOrRemoveAnnotation( CosmosAnnotationNames.PropertyName, name, - fromDataAnnotation); - - return name; - } + fromDataAnnotation)?.Value; /// /// Gets the the property name that the property is mapped to when targeting Cosmos. diff --git a/src/EFCore.Cosmos/Metadata/Conventions/CosmosInversePropertyAttributeConvention.cs b/src/EFCore.Cosmos/Metadata/Conventions/CosmosInversePropertyAttributeConvention.cs index a0880367e00..e183c603bb3 100644 --- a/src/EFCore.Cosmos/Metadata/Conventions/CosmosInversePropertyAttributeConvention.cs +++ b/src/EFCore.Cosmos/Metadata/Conventions/CosmosInversePropertyAttributeConvention.cs @@ -40,12 +40,11 @@ public CosmosInversePropertyAttributeConvention(ProviderConventionSetBuilderDepe Type targetClrType, MemberInfo navigationMemberInfo, bool shouldCreate = true) - => ((InternalEntityTypeBuilder)entityTypeBuilder) -#pragma warning disable EF1001 // Internal EF Core API usage. + => entityTypeBuilder .GetTargetEntityTypeBuilder( targetClrType, navigationMemberInfo, - shouldCreate ? ConfigurationSource.DataAnnotation : null, - CosmosRelationshipDiscoveryConvention.ShouldBeOwnedType(targetClrType, entityTypeBuilder.Metadata.Model)); -#pragma warning restore EF1001 // Internal EF Core API usage. + shouldCreate, + CosmosRelationshipDiscoveryConvention.ShouldBeOwnedType(targetClrType, entityTypeBuilder.Metadata.Model), + fromDataAnnotation: true); } diff --git a/src/EFCore.Relational/Extensions/RelationalEntityTypeExtensions.cs b/src/EFCore.Relational/Extensions/RelationalEntityTypeExtensions.cs index d24502b2549..150739d1642 100644 --- a/src/EFCore.Relational/Extensions/RelationalEntityTypeExtensions.cs +++ b/src/EFCore.Relational/Extensions/RelationalEntityTypeExtensions.cs @@ -112,14 +112,10 @@ public static void SetTableName(this IMutableEntityType entityType, string? name this IConventionEntityType entityType, string? name, bool fromDataAnnotation = false) - { - entityType.SetAnnotation( + => (string?)entityType.SetAnnotation( RelationalAnnotationNames.TableName, Check.NullButNotEmpty(name, nameof(name)), - fromDataAnnotation); - - return name; - } + fromDataAnnotation)?.Value; /// /// Gets the for the table name. @@ -201,14 +197,10 @@ public static void SetSchema(this IMutableEntityType entityType, string? value) this IConventionEntityType entityType, string? value, bool fromDataAnnotation = false) - { - entityType.SetAnnotation( + => (string?)entityType.SetAnnotation( RelationalAnnotationNames.Schema, Check.NullButNotEmpty(value, nameof(value)), - fromDataAnnotation); - - return value; - } + fromDataAnnotation)?.Value; /// /// Gets the for the database schema. @@ -342,14 +334,10 @@ public static void SetViewName(this IMutableEntityType entityType, string? name) this IConventionEntityType entityType, string? name, bool fromDataAnnotation = false) - { - entityType.SetAnnotation( + => (string?)entityType.SetAnnotation( RelationalAnnotationNames.ViewName, Check.NullButNotEmpty(name, nameof(name)), - fromDataAnnotation); - - return name; - } + fromDataAnnotation)?.Value; /// /// Gets the for the view name. @@ -416,14 +404,10 @@ public static void SetViewSchema(this IMutableEntityType entityType, string? val this IConventionEntityType entityType, string? value, bool fromDataAnnotation = false) - { - entityType.SetAnnotation( + => (string?)entityType.SetAnnotation( RelationalAnnotationNames.ViewSchema, Check.NullButNotEmpty(value, nameof(value)), - fromDataAnnotation); - - return value; - } + fromDataAnnotation)?.Value; /// /// Gets the for the view schema. @@ -1082,11 +1066,10 @@ public static void SetComment(this IMutableEntityType entityType, string? commen this IConventionEntityType entityType, string? comment, bool fromDataAnnotation = false) - { - entityType.SetOrRemoveAnnotation(RelationalAnnotationNames.Comment, comment, fromDataAnnotation); - - return comment; - } + => (string?)entityType.SetOrRemoveAnnotation( + RelationalAnnotationNames.Comment, + comment, + fromDataAnnotation)?.Value; /// /// Gets the for the table comment. diff --git a/src/EFCore.Relational/Extensions/RelationalForeignKeyExtensions.cs b/src/EFCore.Relational/Extensions/RelationalForeignKeyExtensions.cs index 123e35010c7..a73acdd107a 100644 --- a/src/EFCore.Relational/Extensions/RelationalForeignKeyExtensions.cs +++ b/src/EFCore.Relational/Extensions/RelationalForeignKeyExtensions.cs @@ -114,14 +114,10 @@ public static void SetConstraintName(this IMutableForeignKey foreignKey, string? this IConventionForeignKey foreignKey, string? value, bool fromDataAnnotation = false) - { - foreignKey.SetOrRemoveAnnotation( + => (string?)foreignKey.SetOrRemoveAnnotation( RelationalAnnotationNames.Name, Check.NullButNotEmpty(value, nameof(value)), - fromDataAnnotation); - - return value; - } + fromDataAnnotation)?.Value; /// /// Gets the for the constraint name. diff --git a/src/EFCore.Relational/Extensions/RelationalIndexExtensions.cs b/src/EFCore.Relational/Extensions/RelationalIndexExtensions.cs index 76492dabbe6..e0fbff82b56 100644 --- a/src/EFCore.Relational/Extensions/RelationalIndexExtensions.cs +++ b/src/EFCore.Relational/Extensions/RelationalIndexExtensions.cs @@ -89,14 +89,10 @@ public static void SetDatabaseName(this IMutableIndex index, string? name) this IConventionIndex index, string? name, bool fromDataAnnotation = false) - { - index.SetOrRemoveAnnotation( + => (string?)index.SetOrRemoveAnnotation( RelationalAnnotationNames.Name, Check.NullButNotEmpty(name, nameof(name)), - fromDataAnnotation); - - return name; - } + fromDataAnnotation)?.Value; /// /// Gets the for the name of the index in the database. @@ -157,14 +153,10 @@ public static void SetFilter(this IMutableIndex index, string? value) /// Indicates whether the configuration was specified using a data annotation. /// The configured value. public static string? SetFilter(this IConventionIndex index, string? value, bool fromDataAnnotation = false) - { - index.SetAnnotation( + => (string?)index.SetAnnotation( RelationalAnnotationNames.Filter, Check.NullButNotEmpty(value, nameof(value)), - fromDataAnnotation); - - return value; - } + fromDataAnnotation)?.Value; /// /// Gets the for the index filter expression. diff --git a/src/EFCore.Relational/Extensions/RelationalKeyExtensions.cs b/src/EFCore.Relational/Extensions/RelationalKeyExtensions.cs index 200d63e33da..2a2ed7426c5 100644 --- a/src/EFCore.Relational/Extensions/RelationalKeyExtensions.cs +++ b/src/EFCore.Relational/Extensions/RelationalKeyExtensions.cs @@ -87,14 +87,10 @@ public static void SetName(this IMutableKey key, string? name) /// Indicates whether the configuration was specified using a data annotation. /// The configured name. public static string? SetName(this IConventionKey key, string? name, bool fromDataAnnotation = false) - { - key.SetOrRemoveAnnotation( + => (string?)key.SetOrRemoveAnnotation( RelationalAnnotationNames.Name, Check.NullButNotEmpty(name, nameof(name)), - fromDataAnnotation); - - return name; - } + fromDataAnnotation)?.Value; /// /// Gets the for the constraint name. diff --git a/src/EFCore.Relational/Extensions/RelationalModelExtensions.cs b/src/EFCore.Relational/Extensions/RelationalModelExtensions.cs index d95a4b7a096..23543aa18f6 100644 --- a/src/EFCore.Relational/Extensions/RelationalModelExtensions.cs +++ b/src/EFCore.Relational/Extensions/RelationalModelExtensions.cs @@ -45,12 +45,9 @@ public static void SetDefaultSchema(this IMutableModel model, string? value) this IConventionModel model, string? value, bool fromDataAnnotation = false) - { - model.SetOrRemoveAnnotation( + => (string?)model.SetOrRemoveAnnotation( RelationalAnnotationNames.DefaultSchema, - Check.NullButNotEmpty(value, nameof(value)), fromDataAnnotation); - return value; - } + Check.NullButNotEmpty(value, nameof(value)), fromDataAnnotation)?.Value; /// /// Returns the configuration source for the default schema. @@ -104,11 +101,10 @@ public static void SetMaxIdentifierLength(this IMutableModel model, int? length) /// Indicates whether the configuration was specified using a data annotation. /// The configured value. public static int? SetMaxIdentifierLength(this IConventionModel model, int? length, bool fromDataAnnotation = false) - { - model.SetOrRemoveAnnotation(RelationalAnnotationNames.MaxIdentifierLength, length, fromDataAnnotation); - - return length; - } + => (int?)model.SetOrRemoveAnnotation( + RelationalAnnotationNames.MaxIdentifierLength, + length, + fromDataAnnotation)?.Value; /// /// Returns the configuration source for . @@ -513,12 +509,9 @@ public static void SetCollation(this IMutableModel model, string? value) /// Indicates whether the configuration was specified using a data annotation. /// The configured collation. public static string? SetCollation(this IConventionModel model, string? value, bool fromDataAnnotation = false) - { - model.SetOrRemoveAnnotation( + => (string?)model.SetOrRemoveAnnotation( RelationalAnnotationNames.Collation, - Check.NullButNotEmpty(value, nameof(value)), fromDataAnnotation); - return value; - } + Check.NullButNotEmpty(value, nameof(value)), fromDataAnnotation)?.Value; /// /// Returns the configuration source for the collation. diff --git a/src/EFCore.Relational/Extensions/RelationalNavigationExtensions.cs b/src/EFCore.Relational/Extensions/RelationalNavigationExtensions.cs index 655f5c4f89e..3092c2d6ddd 100644 --- a/src/EFCore.Relational/Extensions/RelationalNavigationExtensions.cs +++ b/src/EFCore.Relational/Extensions/RelationalNavigationExtensions.cs @@ -47,14 +47,10 @@ public static void SetJsonPropertyName(this IMutableNavigationBase navigation, s this IConventionNavigationBase navigation, string? name, bool fromDataAnnotation = false) - { - navigation.SetOrRemoveAnnotation( + => (string?)navigation.SetOrRemoveAnnotation( RelationalAnnotationNames.JsonPropertyName, Check.NullButNotEmpty(name, nameof(name)), - fromDataAnnotation); - - return name; - } + fromDataAnnotation)?.Value; /// /// Gets the for the JSON property name for a given navigation. diff --git a/src/EFCore.Relational/Extensions/RelationalPropertyExtensions.cs b/src/EFCore.Relational/Extensions/RelationalPropertyExtensions.cs index d046748cac3..fc0bcdd6f4e 100644 --- a/src/EFCore.Relational/Extensions/RelationalPropertyExtensions.cs +++ b/src/EFCore.Relational/Extensions/RelationalPropertyExtensions.cs @@ -246,14 +246,10 @@ public static void SetColumnName(this IMutableProperty property, string? name) this IConventionProperty property, string? name, bool fromDataAnnotation = false) - { - property.SetOrRemoveAnnotation( + => (string?)property.SetOrRemoveAnnotation( RelationalAnnotationNames.ColumnName, Check.NullButNotEmpty(name, nameof(name)), - fromDataAnnotation); - - return name; - } + fromDataAnnotation)?.Value; /// /// Sets the column to which the property is mapped for a particular table-like store object. @@ -352,11 +348,10 @@ public static void SetColumnOrder(this IMutableProperty property, int? order) /// A value indicating whether the configuration was specified using a data annotation. /// The configured value. public static int? SetColumnOrder(this IConventionProperty property, int? order, bool fromDataAnnotation = false) - { - property.SetOrRemoveAnnotation(RelationalAnnotationNames.ColumnOrder, order, fromDataAnnotation); - - return order; - } + => (int?)property.SetOrRemoveAnnotation( + RelationalAnnotationNames.ColumnOrder, + order, + fromDataAnnotation)?.Value; /// /// Gets the of the column order. @@ -446,14 +441,10 @@ public static void SetColumnType(this IMutableProperty property, string? value) this IConventionProperty property, string? value, bool fromDataAnnotation = false) - { - property.SetOrRemoveAnnotation( + => (string?)property.SetOrRemoveAnnotation( RelationalAnnotationNames.ColumnType, Check.NullButNotEmpty(value, nameof(value)), - fromDataAnnotation); - - return value; - } + fromDataAnnotation)?.Value; /// /// Gets the for the column name. @@ -687,14 +678,10 @@ public static void SetDefaultValueSql(this IMutableProperty property, string? va this IConventionProperty property, string? value, bool fromDataAnnotation = false) - { - property.SetOrRemoveAnnotation( + => (string?)property.SetOrRemoveAnnotation( RelationalAnnotationNames.DefaultValueSql, value, - fromDataAnnotation); - - return value; - } + fromDataAnnotation)?.Value; /// /// Gets the for the default value SQL expression. @@ -753,14 +740,10 @@ public static void SetComputedColumnSql(this IMutableProperty property, string? this IConventionProperty property, string? value, bool fromDataAnnotation = false) - { - property.SetOrRemoveAnnotation( + => (string?)property.SetOrRemoveAnnotation( RelationalAnnotationNames.ComputedColumnSql, value, - fromDataAnnotation); - - return value; - } + fromDataAnnotation)?.Value; /// /// Gets the for the computed value SQL expression. @@ -827,11 +810,10 @@ public static void SetIsStored(this IMutableProperty property, bool? value) this IConventionProperty property, bool? value, bool fromDataAnnotation = false) - { - property.SetOrRemoveAnnotation(RelationalAnnotationNames.IsStored, value, fromDataAnnotation); - - return value; - } + => (bool?)property.SetOrRemoveAnnotation( + RelationalAnnotationNames.IsStored, + value, + fromDataAnnotation)?.Value; /// /// Gets the for the computed value SQL expression. @@ -932,12 +914,10 @@ public static void SetDefaultValue(this IMutableProperty property, object? value this IConventionProperty property, object? value, bool fromDataAnnotation = false) - { - property.SetOrRemoveAnnotation( - RelationalAnnotationNames.DefaultValue, ConvertDefaultValue(property, value), fromDataAnnotation); - - return value; - } + => (object?)property.SetOrRemoveAnnotation( + RelationalAnnotationNames.DefaultValue, + ConvertDefaultValue(property, value), + fromDataAnnotation)?.Value; private static object? ConvertDefaultValue(IReadOnlyProperty property, object? value) { @@ -1095,11 +1075,10 @@ public static void SetIsFixedLength(this IMutableProperty property, bool? fixedL this IConventionProperty property, bool? fixedLength, bool fromDataAnnotation = false) - { - property.SetOrRemoveAnnotation(RelationalAnnotationNames.IsFixedLength, fixedLength, fromDataAnnotation); - - return fixedLength; - } + => (bool?)property.SetOrRemoveAnnotation( + RelationalAnnotationNames.IsFixedLength, + fixedLength, + fromDataAnnotation)?.Value; /// /// Gets the for . @@ -1229,11 +1208,10 @@ public static void SetComment(this IMutableProperty property, string? comment) this IConventionProperty property, string? comment, bool fromDataAnnotation = false) - { - property.SetOrRemoveAnnotation(RelationalAnnotationNames.Comment, comment, fromDataAnnotation); - - return comment; - } + => (string?)property.SetOrRemoveAnnotation( + RelationalAnnotationNames.Comment, + comment, + fromDataAnnotation)?.Value; /// /// Gets the for the column comment. @@ -1291,10 +1269,10 @@ public static void SetCollation(this IMutableProperty property, string? collatio this IConventionProperty property, string? collation, bool fromDataAnnotation = false) - { - property.SetOrRemoveAnnotation(RelationalAnnotationNames.Collation, collation, fromDataAnnotation); - return collation; - } + => (string?)property.SetOrRemoveAnnotation( + RelationalAnnotationNames.Collation, + collation, + fromDataAnnotation)?.Value; /// /// Gets the for the column collation. @@ -1960,14 +1938,10 @@ public static void SetJsonPropertyName(this IMutableProperty property, string? n this IConventionProperty property, string? name, bool fromDataAnnotation = false) - { - property.SetOrRemoveAnnotation( + => (string?)property.SetOrRemoveAnnotation( RelationalAnnotationNames.JsonPropertyName, Check.NullButNotEmpty(name, nameof(name)), - fromDataAnnotation); - - return name; - } + fromDataAnnotation)?.Value; /// /// Gets the for the JSON property name for a given entity property. diff --git a/src/EFCore.Relational/Metadata/Internal/StoredProcedure.cs b/src/EFCore.Relational/Metadata/Internal/StoredProcedure.cs index cb99405a6d5..b8f4a7142ca 100644 --- a/src/EFCore.Relational/Metadata/Internal/StoredProcedure.cs +++ b/src/EFCore.Relational/Metadata/Internal/StoredProcedure.cs @@ -134,18 +134,7 @@ public override bool IsReadOnly public static StoredProcedure SetStoredProcedure( IMutableEntityType entityType, StoreObjectType sprocType) - { - var oldId = FindDeclaredStoredProcedure(entityType, sprocType)?.GetStoreIdentifier(); - var sproc = new StoredProcedure(entityType, ConfigurationSource.Explicit); - entityType.SetAnnotation(GetAnnotationName(sprocType), sproc); - - if (oldId != null) - { - UpdateOverrides(oldId.Value, ((IReadOnlyStoredProcedure)sproc).GetStoreIdentifier(), (IConventionEntityType)entityType); - } - - return sproc; - } + => SetStoredProcedure(entityType, sprocType, null, null); /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -156,13 +145,17 @@ public static StoredProcedure SetStoredProcedure( public static StoredProcedure SetStoredProcedure( IMutableEntityType entityType, StoreObjectType sprocType, - string name, + string? name, string? schema) { var oldId = FindDeclaredStoredProcedure(entityType, sprocType)?.GetStoreIdentifier(); var sproc = new StoredProcedure(entityType, ConfigurationSource.Explicit); entityType.SetAnnotation(GetAnnotationName(sprocType), sproc); - sproc.SetName(name, schema, ConfigurationSource.Explicit, skipOverrides: true); + + if (name != null) + { + sproc.SetName(name, schema, ConfigurationSource.Explicit, skipOverrides: true); + } if (oldId != null) { @@ -182,21 +175,7 @@ public static StoredProcedure SetStoredProcedure( IConventionEntityType entityType, StoreObjectType sprocType, bool fromDataAnnotation) - { - var oldId = FindDeclaredStoredProcedure(entityType, sprocType)?.GetStoreIdentifier(); - var sproc = new StoredProcedure( - (IMutableEntityType)entityType, - fromDataAnnotation ? ConfigurationSource.DataAnnotation : ConfigurationSource.Convention); - sproc = (StoredProcedure?)entityType.SetAnnotation(GetAnnotationName(sprocType), sproc)?.Value; - - if (oldId != null - && sproc != null) - { - UpdateOverrides(oldId.Value, ((IReadOnlyStoredProcedure)sproc).GetStoreIdentifier(), entityType); - } - - return sproc; - } + => SetStoredProcedure(entityType, sprocType, null, null, fromDataAnnotation); /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -207,16 +186,19 @@ public static StoredProcedure SetStoredProcedure( public static StoredProcedure? SetStoredProcedure( IConventionEntityType entityType, StoreObjectType sprocType, - string name, + string? name, string? schema, bool fromDataAnnotation) { var oldId = FindDeclaredStoredProcedure(entityType, sprocType)?.GetStoreIdentifier(); var configurationSource = fromDataAnnotation ? ConfigurationSource.DataAnnotation : ConfigurationSource.Convention; var sproc = new StoredProcedure((IMutableEntityType)entityType, configurationSource); - sproc = (StoredProcedure?)entityType.SetAnnotation(GetAnnotationName(sprocType), sproc)?.Value; + sproc = (StoredProcedure?)entityType.SetAnnotation(GetAnnotationName(sprocType), sproc, fromDataAnnotation)?.Value; - sproc?.SetName(name, schema, configurationSource, skipOverrides: true); + if (name != null) + { + sproc?.SetName(name, schema, configurationSource, skipOverrides: true); + } if (oldId != null && sproc != null) diff --git a/src/EFCore.SqlServer/Extensions/SqlServerEntityTypeExtensions.cs b/src/EFCore.SqlServer/Extensions/SqlServerEntityTypeExtensions.cs index 1621ab3248e..57d28e17e22 100644 --- a/src/EFCore.SqlServer/Extensions/SqlServerEntityTypeExtensions.cs +++ b/src/EFCore.SqlServer/Extensions/SqlServerEntityTypeExtensions.cs @@ -45,11 +45,10 @@ public static void SetIsMemoryOptimized(this IMutableEntityType entityType, bool this IConventionEntityType entityType, bool? memoryOptimized, bool fromDataAnnotation = false) - { - entityType.SetOrRemoveAnnotation(SqlServerAnnotationNames.MemoryOptimized, memoryOptimized, fromDataAnnotation); - - return memoryOptimized; - } + => (bool?)entityType.SetOrRemoveAnnotation( + SqlServerAnnotationNames.MemoryOptimized, + memoryOptimized, + fromDataAnnotation)?.Value; /// /// Gets the configuration source for the memory-optimized setting. @@ -86,11 +85,10 @@ public static void SetIsTemporal(this IMutableEntityType entityType, bool tempor this IConventionEntityType entityType, bool? temporal, bool fromDataAnnotation = false) - { - entityType.SetOrRemoveAnnotation(SqlServerAnnotationNames.IsTemporal, temporal, fromDataAnnotation); - - return temporal; - } + => (bool?)entityType.SetOrRemoveAnnotation( + SqlServerAnnotationNames.IsTemporal, + temporal, + fromDataAnnotation)?.Value; /// /// Gets the configuration source for the temporal table setting. @@ -129,14 +127,10 @@ public static void SetPeriodStartPropertyName(this IMutableEntityType entityType this IConventionEntityType entityType, string? periodStartPropertyName, bool fromDataAnnotation = false) - { - entityType.SetAnnotation( + => (string?)entityType.SetAnnotation( SqlServerAnnotationNames.TemporalPeriodStartPropertyName, periodStartPropertyName, - fromDataAnnotation); - - return periodStartPropertyName; - } + fromDataAnnotation)?.Value; /// /// Gets the configuration source for the temporal table period start property name setting. @@ -175,14 +169,10 @@ public static void SetPeriodEndPropertyName(this IMutableEntityType entityType, this IConventionEntityType entityType, string? periodEndPropertyName, bool fromDataAnnotation = false) - { - entityType.SetAnnotation( + => (string?)entityType.SetAnnotation( SqlServerAnnotationNames.TemporalPeriodEndPropertyName, periodEndPropertyName, - fromDataAnnotation); - - return periodEndPropertyName; - } + fromDataAnnotation)?.Value; /// /// Gets the configuration source for the temporal table period end property name setting. @@ -227,14 +217,10 @@ public static void SetHistoryTableName(this IMutableEntityType entityType, strin this IConventionEntityType entityType, string? historyTableName, bool fromDataAnnotation = false) - { - entityType.SetAnnotation( + => (string?)entityType.SetAnnotation( SqlServerAnnotationNames.TemporalHistoryTableName, historyTableName, - fromDataAnnotation); - - return historyTableName; - } + fromDataAnnotation)?.Value; /// /// Gets the configuration source for the temporal history table name setting. @@ -273,14 +259,10 @@ public static void SetHistoryTableSchema(this IMutableEntityType entityType, str this IConventionEntityType entityType, string? historyTableSchema, bool fromDataAnnotation = false) - { - entityType.SetAnnotation( + => (string?)entityType.SetAnnotation( SqlServerAnnotationNames.TemporalHistoryTableSchema, historyTableSchema, - fromDataAnnotation); - - return historyTableSchema; - } + fromDataAnnotation)?.Value; /// /// Gets the configuration source for the temporal history table schema setting. diff --git a/src/EFCore.SqlServer/Extensions/SqlServerIndexExtensions.cs b/src/EFCore.SqlServer/Extensions/SqlServerIndexExtensions.cs index 5a72dc6b76d..7568b318f2b 100644 --- a/src/EFCore.SqlServer/Extensions/SqlServerIndexExtensions.cs +++ b/src/EFCore.SqlServer/Extensions/SqlServerIndexExtensions.cs @@ -70,14 +70,10 @@ public static void SetIsClustered(this IMutableIndex index, bool? value) this IConventionIndex index, bool? value, bool fromDataAnnotation = false) - { - index.SetAnnotation( + => (bool?)index.SetAnnotation( SqlServerAnnotationNames.Clustered, value, - fromDataAnnotation); - - return value; - } + fromDataAnnotation)?.Value; /// /// Returns the for whether the index is clustered. @@ -141,14 +137,10 @@ public static void SetIncludeProperties(this IMutableIndex index, IReadOnlyList< this IConventionIndex index, IReadOnlyList? properties, bool fromDataAnnotation = false) - { - index.SetAnnotation( + => (IReadOnlyList?)index.SetAnnotation( SqlServerAnnotationNames.Include, properties, - fromDataAnnotation); - - return properties; - } + fromDataAnnotation)?.Value; /// /// Returns the for the included property names. @@ -212,14 +204,10 @@ public static void SetIsCreatedOnline(this IMutableIndex index, bool? createdOnl this IConventionIndex index, bool? createdOnline, bool fromDataAnnotation = false) - { - index.SetAnnotation( + => (bool?)index.SetAnnotation( SqlServerAnnotationNames.CreatedOnline, createdOnline, - fromDataAnnotation); - - return createdOnline; - } + fromDataAnnotation)?.Value; /// /// Returns the for whether the index is online. @@ -296,12 +284,10 @@ public static void SetFillFactor(this IMutableIndex index, int? fillFactor) throw new ArgumentOutOfRangeException(nameof(fillFactor)); } - index.SetAnnotation( + return (int?)index.SetAnnotation( SqlServerAnnotationNames.FillFactor, fillFactor, - fromDataAnnotation); - - return fillFactor; + fromDataAnnotation)?.Value; } /// diff --git a/src/EFCore.SqlServer/Extensions/SqlServerKeyExtensions.cs b/src/EFCore.SqlServer/Extensions/SqlServerKeyExtensions.cs index e07ee16fdbc..8f22e06b691 100644 --- a/src/EFCore.SqlServer/Extensions/SqlServerKeyExtensions.cs +++ b/src/EFCore.SqlServer/Extensions/SqlServerKeyExtensions.cs @@ -70,11 +70,10 @@ public static void SetIsClustered(this IMutableKey key, bool? clustered) /// Indicates whether the configuration was specified using a data annotation. /// The configured value. public static bool? SetIsClustered(this IConventionKey key, bool? clustered, bool fromDataAnnotation = false) - { - key.SetOrRemoveAnnotation(SqlServerAnnotationNames.Clustered, clustered, fromDataAnnotation); - - return clustered; - } + => (bool?)key.SetOrRemoveAnnotation( + SqlServerAnnotationNames.Clustered, + clustered, + fromDataAnnotation)?.Value; /// /// Gets the for whether the key is clustered. diff --git a/src/EFCore.SqlServer/Extensions/SqlServerModelExtensions.cs b/src/EFCore.SqlServer/Extensions/SqlServerModelExtensions.cs index aa050ef0aad..2656387110f 100644 --- a/src/EFCore.SqlServer/Extensions/SqlServerModelExtensions.cs +++ b/src/EFCore.SqlServer/Extensions/SqlServerModelExtensions.cs @@ -58,13 +58,10 @@ public static void SetHiLoSequenceName(this IMutableModel model, string? name) this IConventionModel model, string? name, bool fromDataAnnotation = false) - { - Check.NullButNotEmpty(name, nameof(name)); - - model.SetOrRemoveAnnotation(SqlServerAnnotationNames.HiLoSequenceName, name, fromDataAnnotation); - - return name; - } + => (string?)model.SetOrRemoveAnnotation( + SqlServerAnnotationNames.HiLoSequenceName, + Check.NullButNotEmpty(name, nameof(name)), + fromDataAnnotation)?.Value; /// /// Returns the for the default hi-lo sequence name. @@ -106,13 +103,10 @@ public static void SetHiLoSequenceSchema(this IMutableModel model, string? value this IConventionModel model, string? value, bool fromDataAnnotation = false) - { - Check.NullButNotEmpty(value, nameof(value)); - - model.SetOrRemoveAnnotation(SqlServerAnnotationNames.HiLoSequenceSchema, value, fromDataAnnotation); - - return value; - } + => (string?)model.SetOrRemoveAnnotation( + SqlServerAnnotationNames.HiLoSequenceSchema, + Check.NullButNotEmpty(value, nameof(value)), + fromDataAnnotation)?.Value; /// /// Returns the for the default hi-lo sequence schema. @@ -155,13 +149,10 @@ public static void SetSequenceNameSuffix(this IMutableModel model, string? name) this IConventionModel model, string? name, bool fromDataAnnotation = false) - { - Check.NullButNotEmpty(name, nameof(name)); - - model.SetOrRemoveAnnotation(SqlServerAnnotationNames.SequenceNameSuffix, name, fromDataAnnotation); - - return name; - } + => (string?)model.SetOrRemoveAnnotation( + SqlServerAnnotationNames.SequenceNameSuffix, + Check.NullButNotEmpty(name, nameof(name)), + fromDataAnnotation)?.Value; /// /// Returns the for the default value generation sequence name suffix. @@ -203,13 +194,10 @@ public static void SetSequenceSchema(this IMutableModel model, string? value) this IConventionModel model, string? value, bool fromDataAnnotation = false) - { - Check.NullButNotEmpty(value, nameof(value)); - - model.SetOrRemoveAnnotation(SqlServerAnnotationNames.SequenceSchema, value, fromDataAnnotation); - - return value; - } + => (string?)model.SetOrRemoveAnnotation( + SqlServerAnnotationNames.SequenceSchema, + Check.NullButNotEmpty(value, nameof(value)), + fromDataAnnotation)?.Value; /// /// Returns the for the default key value generation sequence schema. @@ -258,14 +246,10 @@ public static void SetIdentitySeed(this IMutableModel model, long? seed) /// Indicates whether the configuration was specified using a data annotation. /// The configured value. public static long? SetIdentitySeed(this IConventionModel model, long? seed, bool fromDataAnnotation = false) - { - model.SetOrRemoveAnnotation( + => (long?)model.SetOrRemoveAnnotation( SqlServerAnnotationNames.IdentitySeed, seed, - fromDataAnnotation); - - return seed; - } + fromDataAnnotation)?.Value; /// /// Returns the for the default schema. @@ -306,14 +290,10 @@ public static void SetIdentityIncrement(this IMutableModel model, int? increment this IConventionModel model, int? increment, bool fromDataAnnotation = false) - { - model.SetOrRemoveAnnotation( + => (int?)model.SetOrRemoveAnnotation( SqlServerAnnotationNames.IdentityIncrement, increment, - fromDataAnnotation); - - return increment; - } + fromDataAnnotation)?.Value; /// /// Returns the for the default identity increment. @@ -355,11 +335,10 @@ public static void SetValueGenerationStrategy( this IConventionModel model, SqlServerValueGenerationStrategy? value, bool fromDataAnnotation = false) - { - model.SetOrRemoveAnnotation(SqlServerAnnotationNames.ValueGenerationStrategy, value, fromDataAnnotation); - - return value; - } + => (SqlServerValueGenerationStrategy?)model.SetOrRemoveAnnotation( + SqlServerAnnotationNames.ValueGenerationStrategy, + value, + fromDataAnnotation)?.Value; /// /// Returns the for the default . @@ -398,11 +377,10 @@ public static void SetDatabaseMaxSize(this IMutableModel model, string? value) this IConventionModel model, string? value, bool fromDataAnnotation = false) - { - model.SetOrRemoveAnnotation(SqlServerAnnotationNames.MaxDatabaseSize, value, fromDataAnnotation); - - return value; - } + => (string?)model.SetOrRemoveAnnotation( + SqlServerAnnotationNames.MaxDatabaseSize, + value, + fromDataAnnotation)?.Value; /// /// Returns the for the maximum size of the database. @@ -441,11 +419,10 @@ public static void SetServiceTierSql(this IMutableModel model, string? value) this IConventionModel model, string? value, bool fromDataAnnotation = false) - { - model.SetOrRemoveAnnotation(SqlServerAnnotationNames.ServiceTierSql, value, fromDataAnnotation); - - return value; - } + => (string?)model.SetOrRemoveAnnotation( + SqlServerAnnotationNames.ServiceTierSql, + value, + fromDataAnnotation)?.Value; /// /// Returns the for the service tier of the database. @@ -484,11 +461,10 @@ public static void SetPerformanceLevelSql(this IMutableModel model, string? valu this IConventionModel model, string? value, bool fromDataAnnotation = false) - { - model.SetOrRemoveAnnotation(SqlServerAnnotationNames.PerformanceLevelSql, value, fromDataAnnotation); - - return value; - } + => (string?)model.SetOrRemoveAnnotation( + SqlServerAnnotationNames.PerformanceLevelSql, + value, + fromDataAnnotation)?.Value; /// /// Returns the for the performance level of the database. diff --git a/src/EFCore.SqlServer/Extensions/SqlServerPropertyExtensions.cs b/src/EFCore.SqlServer/Extensions/SqlServerPropertyExtensions.cs index 7514f415df8..f56c0712e6b 100644 --- a/src/EFCore.SqlServer/Extensions/SqlServerPropertyExtensions.cs +++ b/src/EFCore.SqlServer/Extensions/SqlServerPropertyExtensions.cs @@ -63,14 +63,10 @@ public static void SetHiLoSequenceName(this IMutableProperty property, string? n this IConventionProperty property, string? name, bool fromDataAnnotation = false) - { - property.SetOrRemoveAnnotation( + => (string?)property.SetOrRemoveAnnotation( SqlServerAnnotationNames.HiLoSequenceName, Check.NullButNotEmpty(name, nameof(name)), - fromDataAnnotation); - - return name; - } + fromDataAnnotation)?.Value; /// /// Returns the for the hi-lo sequence name. @@ -126,14 +122,10 @@ public static void SetHiLoSequenceSchema(this IMutableProperty property, string? this IConventionProperty property, string? schema, bool fromDataAnnotation = false) - { - property.SetOrRemoveAnnotation( + => (string?)property.SetOrRemoveAnnotation( SqlServerAnnotationNames.HiLoSequenceSchema, Check.NullButNotEmpty(schema, nameof(schema)), - fromDataAnnotation); - - return schema; - } + fromDataAnnotation)?.Value; /// /// Returns the for the hi-lo sequence schema. @@ -243,14 +235,10 @@ public static void SetSequenceName(this IMutableProperty property, string? name) this IConventionProperty property, string? name, bool fromDataAnnotation = false) - { - property.SetOrRemoveAnnotation( + => (string?)property.SetOrRemoveAnnotation( SqlServerAnnotationNames.SequenceName, Check.NullButNotEmpty(name, nameof(name)), - fromDataAnnotation); - - return name; - } + fromDataAnnotation)?.Value; /// /// Returns the for the key value generation sequence name. @@ -306,14 +294,10 @@ public static void SetSequenceSchema(this IMutableProperty property, string? sch this IConventionProperty property, string? schema, bool fromDataAnnotation = false) - { - property.SetOrRemoveAnnotation( + => (string?)property.SetOrRemoveAnnotation( SqlServerAnnotationNames.SequenceSchema, Check.NullButNotEmpty(schema, nameof(schema)), - fromDataAnnotation); - - return schema; - } + fromDataAnnotation)?.Value; /// /// Returns the for the key value generation sequence schema. @@ -463,14 +447,10 @@ public static void SetIdentitySeed(this IMutableProperty property, long? seed) this IConventionProperty property, long? seed, bool fromDataAnnotation = false) - { - property.SetOrRemoveAnnotation( + => (long?)property.SetOrRemoveAnnotation( SqlServerAnnotationNames.IdentitySeed, seed, - fromDataAnnotation); - - return seed; - } + fromDataAnnotation)?.Value; /// /// Sets the identity seed for a particular table. @@ -872,11 +852,9 @@ private static SqlServerValueGenerationStrategy GetDefaultValueGenerationStrateg public static void SetValueGenerationStrategy( this IMutableProperty property, SqlServerValueGenerationStrategy? value) - { - CheckValueGenerationStrategy(property, value); - - property.SetOrRemoveAnnotation(SqlServerAnnotationNames.ValueGenerationStrategy, value); - } + => property.SetOrRemoveAnnotation( + SqlServerAnnotationNames.ValueGenerationStrategy, + CheckValueGenerationStrategy(property, value)); /// /// Sets the to use for the property. @@ -889,13 +867,10 @@ public static void SetValueGenerationStrategy( this IConventionProperty property, SqlServerValueGenerationStrategy? value, bool fromDataAnnotation = false) - { - CheckValueGenerationStrategy(property, value); - - return (SqlServerValueGenerationStrategy?)property.SetOrRemoveAnnotation( - SqlServerAnnotationNames.ValueGenerationStrategy, value, fromDataAnnotation) - ?.Value; - } + => (SqlServerValueGenerationStrategy?)property.SetOrRemoveAnnotation( + SqlServerAnnotationNames.ValueGenerationStrategy, + CheckValueGenerationStrategy(property, value), + fromDataAnnotation)?.Value; /// /// Sets the to use for the property for a particular table. @@ -934,11 +909,9 @@ public static void SetValueGenerationStrategy( public static void SetValueGenerationStrategy( this IMutableRelationalPropertyOverrides overrides, SqlServerValueGenerationStrategy? value) - { - CheckValueGenerationStrategy(overrides.Property, value); - - overrides.SetOrRemoveAnnotation(SqlServerAnnotationNames.ValueGenerationStrategy, value); - } + => overrides.SetOrRemoveAnnotation( + SqlServerAnnotationNames.ValueGenerationStrategy, + CheckValueGenerationStrategy(overrides.Property, value)); /// /// Sets the to use for the property for a particular table. @@ -951,37 +924,38 @@ public static void SetValueGenerationStrategy( this IConventionRelationalPropertyOverrides overrides, SqlServerValueGenerationStrategy? value, bool fromDataAnnotation = false) - { - CheckValueGenerationStrategy(overrides.Property, value); - - return (SqlServerValueGenerationStrategy?)overrides.SetOrRemoveAnnotation( - SqlServerAnnotationNames.ValueGenerationStrategy, value, fromDataAnnotation) - ?.Value; - } + => (SqlServerValueGenerationStrategy?)overrides.SetOrRemoveAnnotation( + SqlServerAnnotationNames.ValueGenerationStrategy, + CheckValueGenerationStrategy(overrides.Property, value), + fromDataAnnotation)?.Value; - private static void CheckValueGenerationStrategy(IReadOnlyProperty property, SqlServerValueGenerationStrategy? value) + private static SqlServerValueGenerationStrategy? CheckValueGenerationStrategy(IReadOnlyProperty property, SqlServerValueGenerationStrategy? value) { - if (value != null) + if (value == null) { - var propertyType = property.ClrType; + return null; + } - if (value == SqlServerValueGenerationStrategy.IdentityColumn - && !IsCompatibleWithValueGeneration(property)) - { - throw new ArgumentException( - SqlServerStrings.IdentityBadType( - property.Name, property.DeclaringEntityType.DisplayName(), propertyType.ShortDisplayName())); - } + var propertyType = property.ClrType; - if ((value == SqlServerValueGenerationStrategy.SequenceHiLo - || value == SqlServerValueGenerationStrategy.Sequence) - && !IsCompatibleWithValueGeneration(property)) - { - throw new ArgumentException( - SqlServerStrings.SequenceBadType( - property.Name, property.DeclaringEntityType.DisplayName(), propertyType.ShortDisplayName())); - } + if (value == SqlServerValueGenerationStrategy.IdentityColumn + && !IsCompatibleWithValueGeneration(property)) + { + throw new ArgumentException( + SqlServerStrings.IdentityBadType( + property.Name, property.DeclaringEntityType.DisplayName(), propertyType.ShortDisplayName())); + } + + if ((value == SqlServerValueGenerationStrategy.SequenceHiLo + || value == SqlServerValueGenerationStrategy.Sequence) + && !IsCompatibleWithValueGeneration(property)) + { + throw new ArgumentException( + SqlServerStrings.SequenceBadType( + property.Name, property.DeclaringEntityType.DisplayName(), propertyType.ShortDisplayName())); } + + return value; } /// diff --git a/src/EFCore.Sqlite.Core/Extensions/SqlitePropertyExtensions.cs b/src/EFCore.Sqlite.Core/Extensions/SqlitePropertyExtensions.cs index 0f5434a3971..bcf0b3815fb 100644 --- a/src/EFCore.Sqlite.Core/Extensions/SqlitePropertyExtensions.cs +++ b/src/EFCore.Sqlite.Core/Extensions/SqlitePropertyExtensions.cs @@ -56,8 +56,8 @@ public static void SetSrid(this IMutableProperty property, int? value) /// The property. /// The SRID. /// Indicates whether the configuration was specified using a data annotation. - public static void SetSrid(this IConventionProperty property, int? value, bool fromDataAnnotation = false) - => property.SetOrRemoveAnnotation(SqliteAnnotationNames.Srid, value, fromDataAnnotation); + public static int? SetSrid(this IConventionProperty property, int? value, bool fromDataAnnotation = false) + => (int?)property.SetOrRemoveAnnotation(SqliteAnnotationNames.Srid, value, fromDataAnnotation)?.Value; /// /// Gets the for the column SRID. diff --git a/src/EFCore/Metadata/Builders/IConventionEntityTypeBuilder.cs b/src/EFCore/Metadata/Builders/IConventionEntityTypeBuilder.cs index 824e6d9eb32..0e4107ecbec 100644 --- a/src/EFCore/Metadata/Builders/IConventionEntityTypeBuilder.cs +++ b/src/EFCore/Metadata/Builders/IConventionEntityTypeBuilder.cs @@ -1042,4 +1042,20 @@ bool CanHaveSkipNavigation(MemberInfo navigation, bool fromDataAnnotation = fals /// Indicates whether the configuration was specified using a data annotation. /// if the discriminator property can be removed. bool CanRemoveDiscriminator(bool fromDataAnnotation = false); + + /// + /// Gets or creates a builder for the target of a potential navigation. + /// + /// The CLR type of the target. + /// The navigation property. + /// Whether the entity type should be created if currently not in the model. + /// Whether the target should be owned. if it can be either. + /// Indicates whether the configuration was specified using a data annotation. + /// The entity type builder or if not found and can't be created. + IConventionEntityTypeBuilder? GetTargetEntityTypeBuilder( + Type targetClrType, + MemberInfo navigationInfo, + bool createIfMissing = true, + bool? targetShouldBeOwned = null, + bool fromDataAnnotation = false); } diff --git a/src/EFCore/Metadata/Conventions/Internal/ConventionDispatcher.ImmediateConventionScope.cs b/src/EFCore/Metadata/Conventions/Internal/ConventionDispatcher.ImmediateConventionScope.cs index c184c12b43d..f55b9ac520c 100644 --- a/src/EFCore/Metadata/Conventions/Internal/ConventionDispatcher.ImmediateConventionScope.cs +++ b/src/EFCore/Metadata/Conventions/Internal/ConventionDispatcher.ImmediateConventionScope.cs @@ -72,7 +72,7 @@ public IConventionModelBuilder OnModelFinalizing(IConventionModelBuilder modelBu modelConvention.ProcessModelFinalizing(modelBuilder, _modelBuilderConventionContext); if (_modelBuilderConventionContext.ShouldStopProcessing()) { - return _modelBuilderConventionContext.Result!; + return _modelBuilderConventionContext.Result ?? modelBuilder; } } } diff --git a/src/EFCore/Metadata/Conventions/InversePropertyAttributeConvention.cs b/src/EFCore/Metadata/Conventions/InversePropertyAttributeConvention.cs index fdafce4b4e4..50cc2bcae0b 100644 --- a/src/EFCore/Metadata/Conventions/InversePropertyAttributeConvention.cs +++ b/src/EFCore/Metadata/Conventions/InversePropertyAttributeConvention.cs @@ -823,8 +823,12 @@ private static void RemoveInverseNavigation( Type targetClrType, MemberInfo navigationMemberInfo, bool shouldCreate = true) - => ((InternalEntityTypeBuilder)entityTypeBuilder) - .GetTargetEntityTypeBuilder(targetClrType, navigationMemberInfo, shouldCreate ? ConfigurationSource.DataAnnotation : null); + => entityTypeBuilder + .GetTargetEntityTypeBuilder( + targetClrType, + navigationMemberInfo, + shouldCreate, + fromDataAnnotation: true); private static Dictionary References)>? GetInverseNavigations( diff --git a/src/EFCore/Metadata/Conventions/RelationshipDiscoveryConvention.cs b/src/EFCore/Metadata/Conventions/RelationshipDiscoveryConvention.cs index 39a3bc86fbd..02cdca7a499 100644 --- a/src/EFCore/Metadata/Conventions/RelationshipDiscoveryConvention.cs +++ b/src/EFCore/Metadata/Conventions/RelationshipDiscoveryConvention.cs @@ -334,9 +334,11 @@ private List UpdateTargetEntityTypes( { if (shouldCreate) { - var targetEntityTypeBuilder = ((InternalEntityTypeBuilder)entityTypeBuilder) + var targetEntityTypeBuilder = entityTypeBuilder .GetTargetEntityTypeBuilder( - targetClrType, navigationMemberInfo, ConfigurationSource.Convention, + targetClrType, + navigationMemberInfo, + createIfMissing: true, shouldBeOwned ?? ShouldBeOwned(targetClrType, entityTypeBuilder.Metadata.Model)); if (targetEntityTypeBuilder != null) { @@ -344,8 +346,8 @@ private List UpdateTargetEntityTypes( } } - return ((InternalEntityTypeBuilder)entityTypeBuilder) - .GetTargetEntityTypeBuilder(targetClrType, navigationMemberInfo, null, shouldBeOwned); + return entityTypeBuilder + .GetTargetEntityTypeBuilder(targetClrType, navigationMemberInfo, createIfMissing: false, shouldBeOwned); } private static IReadOnlyList RemoveIncompatibleWithExistingRelationships( diff --git a/src/EFCore/Metadata/IConventionNavigationBase.cs b/src/EFCore/Metadata/IConventionNavigationBase.cs index 6241387e269..17cb491991c 100644 --- a/src/EFCore/Metadata/IConventionNavigationBase.cs +++ b/src/EFCore/Metadata/IConventionNavigationBase.cs @@ -26,10 +26,7 @@ public interface IConventionNavigationBase : IReadOnlyNavigationBase, IConventio /// Indicates whether the configuration was specified using a data annotation. /// The configured value. bool? SetIsEagerLoaded(bool? eagerLoaded, bool fromDataAnnotation = false) - { - SetOrRemoveAnnotation(CoreAnnotationNames.EagerLoaded, eagerLoaded, fromDataAnnotation); - return eagerLoaded; - } + => (bool?)SetOrRemoveAnnotation(CoreAnnotationNames.EagerLoaded, eagerLoaded, fromDataAnnotation)?.Value; /// /// Returns the configuration source for . diff --git a/src/EFCore/Metadata/Internal/InternalEntityTypeBuilder.cs b/src/EFCore/Metadata/Internal/InternalEntityTypeBuilder.cs index b585ca277f7..b5e4f151188 100644 --- a/src/EFCore/Metadata/Internal/InternalEntityTypeBuilder.cs +++ b/src/EFCore/Metadata/Internal/InternalEntityTypeBuilder.cs @@ -6151,12 +6151,38 @@ bool IConventionEntityTypeBuilder.CanSetDiscriminator(MemberInfo memberInfo, boo [DebuggerStepThrough] bool IConventionEntityTypeBuilder.CanRemoveDiscriminator(bool fromDataAnnotation) => CanRemoveDiscriminator(fromDataAnnotation ? ConfigurationSource.DataAnnotation : ConfigurationSource.Convention); - - /// + + /// + /// 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. + /// [DebuggerStepThrough] IConventionPropertyBuilder? IConventionEntityTypeBuilder.CreateUniqueProperty( Type propertyType, string basePropertyName, bool required) => CreateUniqueProperty(propertyType, basePropertyName, required); + + /// + /// 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. + /// + [DebuggerStepThrough] + IConventionEntityTypeBuilder? IConventionEntityTypeBuilder.GetTargetEntityTypeBuilder( + Type targetClrType, + MemberInfo navigationInfo, + bool createIfMissing, + bool? targetShouldBeOwned, + bool fromDataAnnotation) + => GetTargetEntityTypeBuilder( + targetClrType, + navigationInfo, + createIfMissing + ? fromDataAnnotation ? ConfigurationSource.DataAnnotation : ConfigurationSource.Convention + : null, + targetShouldBeOwned); } diff --git a/test/EFCore.Cosmos.FunctionalTests/CosmosApiConsistencyTest.cs b/test/EFCore.Cosmos.FunctionalTests/CosmosApiConsistencyTest.cs index 53d89cf01e7..a9788f95152 100644 --- a/test/EFCore.Cosmos.FunctionalTests/CosmosApiConsistencyTest.cs +++ b/test/EFCore.Cosmos.FunctionalTests/CosmosApiConsistencyTest.cs @@ -46,6 +46,14 @@ public override typeof(CosmosModelBuilderExtensions), null ), + ( + typeof(IReadOnlyEntityType), + typeof(CosmosEntityTypeExtensions), + typeof(CosmosEntityTypeExtensions), + typeof(CosmosEntityTypeExtensions), + typeof(CosmosEntityTypeBuilderExtensions), + null + ), ( typeof(IReadOnlyProperty), typeof(CosmosPropertyExtensions), diff --git a/test/EFCore.Sqlite.FunctionalTests/SqliteApiConsistencyTest.cs b/test/EFCore.Sqlite.FunctionalTests/SqliteApiConsistencyTest.cs index f7a351cf90c..03c7069491d 100644 --- a/test/EFCore.Sqlite.FunctionalTests/SqliteApiConsistencyTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/SqliteApiConsistencyTest.cs @@ -27,5 +27,24 @@ public class SqliteApiConsistencyFixture : ApiConsistencyFixtureBase typeof(SqliteDbContextOptionsBuilder), typeof(SqlitePropertyBuilderExtensions) }; + + public override + List<(Type Type, + Type ReadonlyExtensions, + Type MutableExtensions, + Type ConventionExtensions, + Type ConventionBuilderExtensions, + Type RuntimeExtensions)> MetadataExtensionTypes { get; } + = new() + { + ( + typeof(IReadOnlyProperty), + typeof(SqlitePropertyExtensions), + typeof(SqlitePropertyExtensions), + typeof(SqlitePropertyExtensions), + typeof(SqlitePropertyBuilderExtensions), + null + ) + }; } } diff --git a/test/EFCore.Tests/ApiConsistencyTest.cs b/test/EFCore.Tests/ApiConsistencyTest.cs index 270bcf54576..5b4be02d416 100644 --- a/test/EFCore.Tests/ApiConsistencyTest.cs +++ b/test/EFCore.Tests/ApiConsistencyTest.cs @@ -133,6 +133,7 @@ protected override void Initialize() typeof(IConventionAnnotatableBuilder).GetMethod(nameof(IConventionAnnotatableBuilder.HasNonNullAnnotation)), typeof(IConventionEntityTypeBuilder).GetMethod(nameof(IConventionEntityTypeBuilder.RemoveUnusedImplicitProperties)), typeof(IConventionEntityTypeBuilder).GetMethod(nameof(IConventionEntityTypeBuilder.Ignore)), + typeof(IConventionEntityTypeBuilder).GetMethod(nameof(IConventionEntityTypeBuilder.GetTargetEntityTypeBuilder)), typeof(IConventionModelBuilder).GetMethod(nameof(IConventionModelBuilder.Ignore), new[] { typeof(Type), typeof(bool) }), typeof(IConventionModelBuilder).GetMethod(nameof(IConventionModelBuilder.Ignore), new[] { typeof(string), typeof(bool) }), typeof(IConventionPropertyBuilder).GetMethod(