diff --git a/src/EFCore.Cosmos/Extensions/CosmosEntityTypeBuilderExtensions.cs b/src/EFCore.Cosmos/Extensions/CosmosEntityTypeBuilderExtensions.cs index 7e92cde073d..c1a0aead1fa 100644 --- a/src/EFCore.Cosmos/Extensions/CosmosEntityTypeBuilderExtensions.cs +++ b/src/EFCore.Cosmos/Extensions/CosmosEntityTypeBuilderExtensions.cs @@ -1,7 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System; using System.Linq.Expressions; using System.Reflection; using Microsoft.Azure.Cosmos; @@ -115,10 +114,10 @@ public static OwnedNavigationBuilder ToJsonProperty( /// The builder for the entity type being configured. /// The name of the parent property. /// The same builder instance so that multiple calls can be chained. - public static OwnedNavigationBuilder ToJsonProperty( - this OwnedNavigationBuilder entityTypeBuilder, + public static OwnedNavigationBuilder ToJsonProperty( + this OwnedNavigationBuilder entityTypeBuilder, string? name) - where TEntity : class + where TOwnerEntity : class where TDependentEntity : class { entityTypeBuilder.OwnedEntityType.SetContainingPropertyName(name); diff --git a/src/EFCore.Design/Design/Internal/CSharpHelper.cs b/src/EFCore.Design/Design/Internal/CSharpHelper.cs index de1d417f304..2dcda7cbc64 100644 --- a/src/EFCore.Design/Design/Internal/CSharpHelper.cs +++ b/src/EFCore.Design/Design/Internal/CSharpHelper.cs @@ -1,11 +1,8 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System; using System.Collections; -using System.Collections.Generic; using System.Globalization; -using System.Linq; using System.Linq.Expressions; using System.Numerics; using System.Text; @@ -137,7 +134,7 @@ public CSharpHelper(ITypeMappingSource typeMappingSource) { typeof(Guid), (c, v) => c.Literal((Guid)v) }, { typeof(int), (c, v) => c.Literal((int)v) }, { typeof(long), (c, v) => c.Literal((long)v) }, - { typeof(NestedClosureCodeFragment), (c, v) => c.Fragment((NestedClosureCodeFragment)v) }, + { typeof(NestedClosureCodeFragment), (c, v) => c.Fragment((NestedClosureCodeFragment)v, 0) }, { typeof(object[]), (c, v) => c.Literal((object[])v) }, { typeof(object[,]), (c, v) => c.Literal((object[,])v) }, { typeof(sbyte), (c, v) => c.Literal((sbyte)v) }, @@ -971,8 +968,11 @@ private bool HandleList(IEnumerable argumentExpressions, StringBuild /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public virtual string Fragment(MethodCallCodeFragment fragment) + => Fragment(fragment, indent: 0); + + private string Fragment(MethodCallCodeFragment fragment, int indent) { - var builder = new StringBuilder(); + var builder = new IndentedStringBuilder(); var current = fragment; while (current != null) @@ -989,7 +989,15 @@ public virtual string Fragment(MethodCallCodeFragment fragment) builder.Append(", "); } - builder.Append(UnknownLiteral(current.Arguments[i])); + var argument = current.Arguments[i]; + if (argument is NestedClosureCodeFragment nestedFragment) + { + builder.Append(Fragment(nestedFragment, indent)); + } + else + { + builder.Append(UnknownLiteral(argument)); + } } builder.Append(')'); @@ -1000,21 +1008,25 @@ public virtual string Fragment(MethodCallCodeFragment fragment) return builder.ToString(); } - private string Fragment(NestedClosureCodeFragment fragment) + private string Fragment(NestedClosureCodeFragment fragment, int indent) { if (fragment.MethodCalls.Count == 1) { - return fragment.Parameter + " => " + fragment.Parameter + Fragment(fragment.MethodCalls[0]); + return fragment.Parameter + " => " + fragment.Parameter + Fragment(fragment.MethodCalls[0], indent); } var builder = new IndentedStringBuilder(); builder.AppendLine(fragment.Parameter + " =>"); + for (var i = -1; i < indent; i++) + { + builder.IncrementIndent(); + } builder.AppendLine("{"); using (builder.Indent()) { foreach (var methodCall in fragment.MethodCalls) { - builder.Append(fragment.Parameter + Fragment(methodCall)); + builder.Append(fragment.Parameter + Fragment(methodCall, indent + 1)); builder.AppendLine(";"); } } diff --git a/src/EFCore.Design/Migrations/Design/CSharpSnapshotGenerator.cs b/src/EFCore.Design/Migrations/Design/CSharpSnapshotGenerator.cs index 39e14840c05..6fa0c7716e1 100644 --- a/src/EFCore.Design/Migrations/Design/CSharpSnapshotGenerator.cs +++ b/src/EFCore.Design/Migrations/Design/CSharpSnapshotGenerator.cs @@ -1,10 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System; -using System.Collections.Generic; using System.Collections.Immutable; -using System.Linq; using Microsoft.EntityFrameworkCore.Design; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Metadata; @@ -835,7 +832,7 @@ protected virtual void GenerateEntityTypeAnnotations( .Append(".ToTable("); if (tableName == null - && schemaAnnotation == null) + && (schemaAnnotation == null || schemaAnnotation.Value == null)) { stringBuilder.Append("(string)"); } @@ -848,7 +845,8 @@ protected virtual void GenerateEntityTypeAnnotations( } var isExcludedAnnotation = annotations.Find(RelationalAnnotationNames.IsTableExcludedFromMigrations); - if (schemaAnnotation != null) + if (schemaAnnotation != null + && (tableName != null || schemaAnnotation.Value != null)) { stringBuilder .Append(", "); @@ -866,17 +864,8 @@ protected virtual void GenerateEntityTypeAnnotations( { if (((bool?)isExcludedAnnotation.Value) == true) { - if (entityType.IsOwned()) - { - // Issue #23173 - stringBuilder - .Append(", excludedFromMigrations: true"); - } - else - { - stringBuilder - .Append(", t => t.ExcludeFromMigrations()"); - } + stringBuilder + .Append(", t => t.ExcludeFromMigrations()"); } annotations.Remove(isExcludedAnnotation.Name); @@ -1041,7 +1030,7 @@ protected virtual void GenerateEntityTypeAnnotations( { stringBuilder .AppendLine() - .Append(Code.Fragment(methodCallCodeFragment)); + .AppendLines(Code.Fragment(methodCallCodeFragment), skipFinalNewline: true); } GenerateAnnotations(annotations.Values, stringBuilder); diff --git a/src/EFCore.Relational/Extensions/RelationalEntityTypeBuilderExtensions.cs b/src/EFCore.Relational/Extensions/RelationalEntityTypeBuilderExtensions.cs index 2c306a6b10a..4cc9f959d63 100644 --- a/src/EFCore.Relational/Extensions/RelationalEntityTypeBuilderExtensions.cs +++ b/src/EFCore.Relational/Extensions/RelationalEntityTypeBuilderExtensions.cs @@ -1,9 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System; using System.Diagnostics.CodeAnalysis; -using System.Linq; using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Metadata.Builders; using Microsoft.EntityFrameworkCore.Metadata.Internal; @@ -26,7 +24,14 @@ public static class RelationalEntityTypeBuilderExtensions public static EntityTypeBuilder ToTable( this EntityTypeBuilder entityTypeBuilder, string? name) - => entityTypeBuilder.ToTable(name, (string?)null); + { + Check.NullButNotEmpty(name, nameof(name)); + + entityTypeBuilder.Metadata.SetTableName(name); + entityTypeBuilder.Metadata.SetSchema(null); + + return entityTypeBuilder; + } /// /// Configures the table that the entity type maps to when targeting a relational database. @@ -38,7 +43,9 @@ public static EntityTypeBuilder ToTable( this EntityTypeBuilder entityTypeBuilder, Action buildAction) { - buildAction(new TableBuilder(null, null, entityTypeBuilder)); + Check.NotNull(buildAction, nameof(buildAction)); + + buildAction(new TableBuilder(null, null, entityTypeBuilder.Metadata)); return entityTypeBuilder; } @@ -52,9 +59,18 @@ public static EntityTypeBuilder ToTable( /// The same builder instance so that multiple calls can be chained. public static EntityTypeBuilder ToTable( this EntityTypeBuilder entityTypeBuilder, - string name, + string? name, Action buildAction) - => entityTypeBuilder.ToTable(name, null, buildAction); + { + Check.NullButNotEmpty(name, nameof(name)); + Check.NotNull(buildAction, nameof(buildAction)); + + entityTypeBuilder.Metadata.SetTableName(name); + entityTypeBuilder.Metadata.SetSchema(null); + buildAction(new TableBuilder(name, null, entityTypeBuilder.Metadata)); + + return entityTypeBuilder; + } /// /// Configures the table that the entity type maps to when targeting a relational database. @@ -67,7 +83,7 @@ public static EntityTypeBuilder ToTable( this EntityTypeBuilder entityTypeBuilder, string? name) where TEntity : class - => entityTypeBuilder.ToTable(name, (string?)null); + => (EntityTypeBuilder)((EntityTypeBuilder)entityTypeBuilder).ToTable(name); /// /// Configures the table that the entity type maps to when targeting a relational database. @@ -81,7 +97,9 @@ public static EntityTypeBuilder ToTable( Action> buildAction) where TEntity : class { - buildAction(new TableBuilder(null, null, entityTypeBuilder)); + Check.NotNull(buildAction, nameof(buildAction)); + + buildAction(new TableBuilder(null, null, entityTypeBuilder.Metadata)); return entityTypeBuilder; } @@ -96,25 +114,19 @@ public static EntityTypeBuilder ToTable( /// The same builder instance so that multiple calls can be chained. public static EntityTypeBuilder ToTable( this EntityTypeBuilder entityTypeBuilder, - string name, - Action buildAction) - where TEntity : class - => entityTypeBuilder.ToTable(name, null, buildAction); - - /// - /// Configures the table that the entity type maps to when targeting a relational database. - /// - /// The entity type being configured. - /// The builder for the entity type being configured. - /// The name of the table. - /// An action that performs configuration of the table. - /// The same builder instance so that multiple calls can be chained. - public static EntityTypeBuilder ToTable( - this EntityTypeBuilder entityTypeBuilder, - string name, + string? name, Action> buildAction) where TEntity : class - => entityTypeBuilder.ToTable(name, null, buildAction); + { + Check.NullButNotEmpty(name, nameof(name)); + Check.NotNull(buildAction, nameof(buildAction)); + + entityTypeBuilder.Metadata.SetTableName(name); + entityTypeBuilder.Metadata.SetSchema(null); + buildAction(new TableBuilder(name, null, entityTypeBuilder.Metadata)); + + return entityTypeBuilder; + } /// /// Configures the table that the entity type maps to when targeting a relational database. @@ -125,9 +137,12 @@ public static EntityTypeBuilder ToTable( /// The same builder instance so that multiple calls can be chained. public static EntityTypeBuilder ToTable( this EntityTypeBuilder entityTypeBuilder, - string? name, + string name, string? schema) { + Check.NotNull(name, nameof(name)); + Check.NullButNotEmpty(schema, nameof(schema)); + entityTypeBuilder.Metadata.SetTableName(name); entityTypeBuilder.Metadata.SetSchema(schema); return entityTypeBuilder; @@ -149,10 +164,11 @@ public static EntityTypeBuilder ToTable( { Check.NotNull(name, nameof(name)); Check.NullButNotEmpty(schema, nameof(schema)); + Check.NotNull(buildAction, nameof(buildAction)); - buildAction(new TableBuilder(name, schema, entityTypeBuilder)); entityTypeBuilder.Metadata.SetTableName(name); entityTypeBuilder.Metadata.SetSchema(schema); + buildAction(new TableBuilder(name, schema, entityTypeBuilder.Metadata)); return entityTypeBuilder; } @@ -164,34 +180,13 @@ public static EntityTypeBuilder ToTable( /// The builder for the entity type being configured. /// The name of the table. /// The schema of the table. - /// An action that performs configuration of the table. /// The same builder instance so that multiple calls can be chained. public static EntityTypeBuilder ToTable( this EntityTypeBuilder entityTypeBuilder, string name, - string? schema, - Action buildAction) - where TEntity : class - => (EntityTypeBuilder)((EntityTypeBuilder)entityTypeBuilder).ToTable(name, schema, buildAction); - - /// - /// Configures the table that the entity type maps to when targeting a relational database. - /// - /// The entity type being configured. - /// The builder for the entity type being configured. - /// The name of the table. - /// The schema of the table. - /// The same builder instance so that multiple calls can be chained. - public static EntityTypeBuilder ToTable( - this EntityTypeBuilder entityTypeBuilder, - string? name, string? schema) where TEntity : class - { - entityTypeBuilder.Metadata.SetTableName(name); - entityTypeBuilder.Metadata.SetSchema(schema); - return entityTypeBuilder; - } + => (EntityTypeBuilder)((EntityTypeBuilder)entityTypeBuilder).ToTable(name, schema); /// /// Configures the table that the entity type maps to when targeting a relational database. @@ -211,10 +206,11 @@ public static EntityTypeBuilder ToTable( { Check.NotNull(name, nameof(name)); Check.NullButNotEmpty(schema, nameof(schema)); + Check.NotNull(buildAction, nameof(buildAction)); - buildAction(new TableBuilder(name, schema, entityTypeBuilder)); entityTypeBuilder.Metadata.SetTableName(name); entityTypeBuilder.Metadata.SetSchema(schema); + buildAction(new TableBuilder(name, schema, entityTypeBuilder.Metadata)); return entityTypeBuilder; } @@ -228,7 +224,50 @@ public static EntityTypeBuilder ToTable( public static OwnedNavigationBuilder ToTable( this OwnedNavigationBuilder referenceOwnershipBuilder, string? name) - => ToTable(referenceOwnershipBuilder, name, schema: null, excludedFromMigrations: null); + { + Check.NullButNotEmpty(name, nameof(name)); + + referenceOwnershipBuilder.OwnedEntityType.SetTableName(name); + referenceOwnershipBuilder.OwnedEntityType.SetSchema(null); + + return referenceOwnershipBuilder; + } + + /// + /// Configures the table that the entity type maps to when targeting a relational database. + /// + /// The builder for the entity type being configured. + /// An action that performs configuration of the table. + /// The same builder instance so that multiple calls can be chained. + public static OwnedNavigationBuilder ToTable( + this OwnedNavigationBuilder referenceOwnershipBuilder, + Action buildAction) + { + Check.NotNull(buildAction, nameof(buildAction)); + + buildAction(new TableBuilder(null, null, referenceOwnershipBuilder.OwnedEntityType)); + + return referenceOwnershipBuilder; + } + + /// + /// Configures the table that the entity type maps to when targeting a relational database. + /// + /// The builder for the entity type being configured. + /// An action that performs configuration of the table. + /// The same builder instance so that multiple calls can be chained. + public static OwnedNavigationBuilder ToTable( + this OwnedNavigationBuilder referenceOwnershipBuilder, + Action> buildAction) + where TOwnerEntity : class + where TRelatedEntity : class + { + Check.NotNull(buildAction, nameof(buildAction)); + + buildAction(new TableBuilder(null, null, referenceOwnershipBuilder.OwnedEntityType)); + + return referenceOwnershipBuilder; + } /// /// Configures the table that the entity type maps to when targeting a relational database. @@ -237,6 +276,7 @@ public static OwnedNavigationBuilder ToTable( /// The name of the table. /// A value indicating whether the table should be managed by migrations. /// The same builder instance so that multiple calls can be chained. + [Obsolete("Use the overload with an Action parameter")] public static OwnedNavigationBuilder ToTable( this OwnedNavigationBuilder referenceOwnershipBuilder, string? name, @@ -246,37 +286,79 @@ public static OwnedNavigationBuilder ToTable( /// /// Configures the table that the entity type maps to when targeting a relational database. /// - /// The entity type being configured. - /// The entity type that this relationship targets. /// The builder for the entity type being configured. /// The name of the table. /// The same builder instance so that multiple calls can be chained. - public static OwnedNavigationBuilder ToTable( - this OwnedNavigationBuilder referenceOwnershipBuilder, + public static OwnedNavigationBuilder ToTable( + this OwnedNavigationBuilder referenceOwnershipBuilder, string? name) - where TEntity : class + where TOwnerEntity : class where TRelatedEntity : class - => (OwnedNavigationBuilder)ToTable( - referenceOwnershipBuilder, name, schema: null, excludedFromMigrations: null); + => (OwnedNavigationBuilder)((OwnedNavigationBuilder)referenceOwnershipBuilder).ToTable(name); + + /// + /// Configures the table that the entity type maps to when targeting a relational database. + /// + /// The builder for the entity type being configured. + /// The name of the table. + /// An action that performs configuration of the table. + /// The same builder instance so that multiple calls can be chained. + public static OwnedNavigationBuilder ToTable( + this OwnedNavigationBuilder referenceOwnershipBuilder, + string? name, + Action buildAction) + { + Check.NullButNotEmpty(name, nameof(name)); + Check.NotNull(buildAction, nameof(buildAction)); + + referenceOwnershipBuilder.OwnedEntityType.SetTableName(name); + referenceOwnershipBuilder.OwnedEntityType.SetSchema(null); + buildAction(new TableBuilder(name, null, referenceOwnershipBuilder.OwnedEntityType)); + + return referenceOwnershipBuilder; + } /// /// Configures the table that the entity type maps to when targeting a relational database. /// - /// The entity type being configured. - /// The entity type that this relationship targets. /// The builder for the entity type being configured. /// The name of the table. /// A value indicating whether the table should be managed by migrations. /// The same builder instance so that multiple calls can be chained. - public static OwnedNavigationBuilder ToTable( - this OwnedNavigationBuilder referenceOwnershipBuilder, + [Obsolete("Use the overload with an Action parameter")] + public static OwnedNavigationBuilder ToTable( + this OwnedNavigationBuilder referenceOwnershipBuilder, string? name, bool excludedFromMigrations) - where TEntity : class + where TOwnerEntity : class where TRelatedEntity : class - => (OwnedNavigationBuilder)ToTable( + => (OwnedNavigationBuilder)ToTable( (OwnedNavigationBuilder)referenceOwnershipBuilder, name, excludedFromMigrations); + /// + /// Configures the table that the entity type maps to when targeting a relational database. + /// + /// The builder for the entity type being configured. + /// The name of the table. + /// An action that performs configuration of the table. + /// The same builder instance so that multiple calls can be chained. + public static OwnedNavigationBuilder ToTable( + this OwnedNavigationBuilder referenceOwnershipBuilder, + string? name, + Action> buildAction) + where TOwnerEntity : class + where TRelatedEntity : class + { + Check.NullButNotEmpty(name, nameof(name)); + Check.NotNull(buildAction, nameof(buildAction)); + + referenceOwnershipBuilder.OwnedEntityType.SetTableName(name); + referenceOwnershipBuilder.OwnedEntityType.SetSchema(null); + buildAction(new TableBuilder(name, null, referenceOwnershipBuilder.OwnedEntityType)); + + return referenceOwnershipBuilder; + } + /// /// Configures the table that the entity type maps to when targeting a relational database. /// @@ -286,9 +368,17 @@ public static OwnedNavigationBuilder ToTable The same builder instance so that multiple calls can be chained. public static OwnedNavigationBuilder ToTable( this OwnedNavigationBuilder referenceOwnershipBuilder, - string? name, + string name, string? schema) - => ToTable(referenceOwnershipBuilder, name, schema, excludedFromMigrations: null); + { + Check.NotNull(name, nameof(name)); + Check.NullButNotEmpty(schema, nameof(schema)); + + referenceOwnershipBuilder.OwnedEntityType.SetTableName(name); + referenceOwnershipBuilder.OwnedEntityType.SetSchema(schema); + + return referenceOwnershipBuilder; + } /// /// Configures the table that the entity type maps to when targeting a relational database. @@ -298,6 +388,7 @@ public static OwnedNavigationBuilder ToTable( /// The schema of the table. /// A value indicating whether the table should be managed by migrations. /// The same builder instance so that multiple calls can be chained. + [Obsolete("Use the overload with an Action parameter")] public static OwnedNavigationBuilder ToTable( this OwnedNavigationBuilder referenceOwnershipBuilder, string? name, @@ -311,19 +402,27 @@ public static OwnedNavigationBuilder ToTable( return ToTable(referenceOwnershipBuilder, name, schema, (bool?)excludedFromMigrations); } - private static OwnedNavigationBuilder ToTable( - OwnedNavigationBuilder referenceOwnershipBuilder, - string? name, + /// + /// Configures the table that the entity type maps to when targeting a relational database. + /// + /// The builder for the entity type being configured. + /// The name of the table. + /// The schema of the table. + /// An action that performs configuration of the table. + /// The same builder instance so that multiple calls can be chained. + public static OwnedNavigationBuilder ToTable( + this OwnedNavigationBuilder referenceOwnershipBuilder, + string name, string? schema, - bool? excludedFromMigrations) + Action buildAction) { + Check.NotNull(name, nameof(name)); + Check.NullButNotEmpty(schema, nameof(schema)); + Check.NotNull(buildAction, nameof(buildAction)); + referenceOwnershipBuilder.OwnedEntityType.SetTableName(name); referenceOwnershipBuilder.OwnedEntityType.SetSchema(schema); - - if (excludedFromMigrations.HasValue) - { - referenceOwnershipBuilder.OwnedEntityType.SetIsTableExcludedFromMigrations(excludedFromMigrations.Value); - } + buildAction(new TableBuilder(name, schema, referenceOwnershipBuilder.OwnedEntityType)); return referenceOwnershipBuilder; } @@ -331,41 +430,82 @@ private static OwnedNavigationBuilder ToTable( /// /// Configures the table that the entity type maps to when targeting a relational database. /// - /// The entity type being configured. - /// The entity type that this relationship targets. /// The builder for the entity type being configured. /// The name of the table. /// The schema of the table. /// The same builder instance so that multiple calls can be chained. - public static OwnedNavigationBuilder ToTable( - this OwnedNavigationBuilder referenceOwnershipBuilder, - string? name, + public static OwnedNavigationBuilder ToTable( + this OwnedNavigationBuilder referenceOwnershipBuilder, + string name, string? schema) - where TEntity : class + where TOwnerEntity : class where TRelatedEntity : class - => (OwnedNavigationBuilder)ToTable( - referenceOwnershipBuilder, name, schema, excludedFromMigrations: null); + => (OwnedNavigationBuilder)((OwnedNavigationBuilder)referenceOwnershipBuilder).ToTable(name, schema); /// /// Configures the table that the entity type maps to when targeting a relational database. /// - /// The entity type being configured. - /// The entity type that this relationship targets. /// The builder for the entity type being configured. /// The name of the table. /// The schema of the table. /// A value indicating whether the table should be managed by migrations. /// The same builder instance so that multiple calls can be chained. - public static OwnedNavigationBuilder ToTable( - this OwnedNavigationBuilder referenceOwnershipBuilder, + [Obsolete("Use the overload with an Action parameter")] + public static OwnedNavigationBuilder ToTable( + this OwnedNavigationBuilder referenceOwnershipBuilder, string? name, string? schema, bool excludedFromMigrations) - where TEntity : class + where TOwnerEntity : class where TRelatedEntity : class - => (OwnedNavigationBuilder)ToTable( + => (OwnedNavigationBuilder)ToTable( (OwnedNavigationBuilder)referenceOwnershipBuilder, name, schema, excludedFromMigrations); + /// + /// Configures the table that the entity type maps to when targeting a relational database. + /// + /// The builder for the entity type being configured. + /// The name of the table. + /// The schema of the table. + /// An action that performs configuration of the table. + /// The same builder instance so that multiple calls can be chained. + public static OwnedNavigationBuilder ToTable( + this OwnedNavigationBuilder referenceOwnershipBuilder, + string name, + string? schema, + Action> buildAction) + where TOwnerEntity : class + where TRelatedEntity : class + { + Check.NotNull(name, nameof(name)); + Check.NullButNotEmpty(schema, nameof(schema)); + Check.NotNull(buildAction, nameof(buildAction)); + + referenceOwnershipBuilder.OwnedEntityType.SetTableName(name); + referenceOwnershipBuilder.OwnedEntityType.SetSchema(schema); + buildAction(new TableBuilder(name, schema, referenceOwnershipBuilder.OwnedEntityType)); + + return referenceOwnershipBuilder; + } + + [Obsolete] + private static OwnedNavigationBuilder ToTable( + OwnedNavigationBuilder referenceOwnershipBuilder, + string? name, + string? schema, + bool? excludedFromMigrations) + { + referenceOwnershipBuilder.OwnedEntityType.SetTableName(name); + referenceOwnershipBuilder.OwnedEntityType.SetSchema(schema); + + if (excludedFromMigrations.HasValue) + { + referenceOwnershipBuilder.OwnedEntityType.SetIsTableExcludedFromMigrations(excludedFromMigrations.Value); + } + + return referenceOwnershipBuilder; + } + /// /// Configures the table that the entity type maps to when targeting a relational database. /// @@ -866,34 +1006,30 @@ public static OwnedNavigationBuilder ToFunction( /// /// Configures the function that the entity type maps to when targeting a relational database. /// - /// The entity type being configured. - /// The entity type that this relationship targets. /// The builder for the entity type being configured. /// The name of the function. /// The function configuration builder. - public static OwnedNavigationBuilder ToFunction( - this OwnedNavigationBuilder referenceOwnershipBuilder, + public static OwnedNavigationBuilder ToFunction( + this OwnedNavigationBuilder referenceOwnershipBuilder, string? name) - where TEntity : class + where TOwnerEntity : class where TRelatedEntity : class - => (OwnedNavigationBuilder)ToFunction((OwnedNavigationBuilder)referenceOwnershipBuilder, name); + => (OwnedNavigationBuilder)ToFunction((OwnedNavigationBuilder)referenceOwnershipBuilder, name); /// /// Configures the function that the entity type maps to when targeting a relational database. /// - /// The entity type being configured. - /// The entity type that this relationship targets. /// The builder for the entity type being configured. /// The name of the function. /// The function configuration action. /// The same builder instance so that multiple calls can be chained. - public static OwnedNavigationBuilder ToFunction( - this OwnedNavigationBuilder referenceOwnershipBuilder, + public static OwnedNavigationBuilder ToFunction( + this OwnedNavigationBuilder referenceOwnershipBuilder, string name, Action configureFunction) - where TEntity : class + where TOwnerEntity : class where TRelatedEntity : class - => (OwnedNavigationBuilder)ToFunction( + => (OwnedNavigationBuilder)ToFunction( (OwnedNavigationBuilder)referenceOwnershipBuilder, name, configureFunction); [return: NotNullIfNotNull("name")] @@ -1038,6 +1174,89 @@ public static EntityTypeBuilder HasCheckConstraint( where TEntity : class => (EntityTypeBuilder)HasCheckConstraint((EntityTypeBuilder)entityTypeBuilder, name, sql, buildAction); + /// + /// Configures a database check constraint when targeting a relational database. + /// + /// The navigation builder for the owned type. + /// The name of the check constraint. + /// The logical constraint sql used in the check constraint. + /// A builder to further configure the navigation. + public static OwnedNavigationBuilder HasCheckConstraint( + this OwnedNavigationBuilder ownedNavigationBuilder, + string name, + string? sql) + { + Check.NotNull(ownedNavigationBuilder, nameof(ownedNavigationBuilder)); + + InternalCheckConstraintBuilder.HasCheckConstraint( + (IConventionEntityType)ownedNavigationBuilder.OwnedEntityType, + name, + sql, + ConfigurationSource.Explicit); + + return ownedNavigationBuilder; + } + + /// + /// Configures a database check constraint when targeting a relational database. + /// + /// The navigation builder for the owned type. + /// The name of the check constraint. + /// The logical constraint sql used in the check constraint. + /// A builder to further configure the navigation. + public static OwnedNavigationBuilder HasCheckConstraint( + this OwnedNavigationBuilder ownedNavigationBuilder, + string name, + string? sql) + where TOwnerEntity : class + where TDependentEntity : class + => (OwnedNavigationBuilder) + HasCheckConstraint((OwnedNavigationBuilder)ownedNavigationBuilder, name, sql); + + /// + /// Configures a database check constraint when targeting a relational database. + /// + /// The navigation builder for the owned type. + /// The name of the check constraint. + /// The logical constraint sql used in the check constraint. + /// An action that performs configuration of the check constraint. + /// A builder to further configure the navigation. + public static OwnedNavigationBuilder HasCheckConstraint( + this OwnedNavigationBuilder ownedNavigationBuilder, + string name, + string sql, + Action buildAction) + { + Check.NotEmpty(sql, nameof(sql)); + Check.NotNull(buildAction, nameof(buildAction)); + + ownedNavigationBuilder.HasCheckConstraint(name, sql); + + buildAction(new CheckConstraintBuilder(ownedNavigationBuilder.OwnedEntityType.FindCheckConstraint(name)!)); + + return ownedNavigationBuilder; + } + + /// + /// Configures a database check constraint when targeting a relational database. + /// + /// The entity type owning the relationship. + /// The dependent entity type of the relationship. + /// The navigation builder for the owned type. + /// The name of the check constraint. + /// The logical constraint sql used in the check constraint. + /// An action that performs configuration of the check constraint. + /// A builder to further configure the navigation. + public static OwnedNavigationBuilder HasCheckConstraint( + this OwnedNavigationBuilder ownedNavigationBuilder, + string name, + string sql, + Action buildAction) + where TOwnerEntity : class + where TDependentEntity : class + => (OwnedNavigationBuilder) + HasCheckConstraint((OwnedNavigationBuilder)ownedNavigationBuilder, name, sql, buildAction); + /// /// Configures a database check constraint when targeting a relational database. /// diff --git a/src/EFCore.Relational/Extensions/RelationalOwnedNavigationBuilderExtensions.cs b/src/EFCore.Relational/Extensions/RelationalOwnedNavigationBuilderExtensions.cs deleted file mode 100644 index 1cefcfefbc9..00000000000 --- a/src/EFCore.Relational/Extensions/RelationalOwnedNavigationBuilderExtensions.cs +++ /dev/null @@ -1,103 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using Microsoft.EntityFrameworkCore.Metadata; -using Microsoft.EntityFrameworkCore.Metadata.Builders; -using Microsoft.EntityFrameworkCore.Metadata.Internal; -using Microsoft.EntityFrameworkCore.Utilities; - -// ReSharper disable once CheckNamespace -namespace Microsoft.EntityFrameworkCore -{ - /// - /// Relational database specific extension methods for . - /// - public static class RelationalOwnedNavigationBuilderExtensions - { - /// - /// Configures a database check constraint when targeting a relational database. - /// - /// The navigation builder for the owned type. - /// The name of the check constraint. - /// The logical constraint sql used in the check constraint. - /// A builder to further configure the navigation. - public static OwnedNavigationBuilder HasCheckConstraint( - this OwnedNavigationBuilder ownedNavigationBuilder, - string name, - string? sql) - { - Check.NotNull(ownedNavigationBuilder, nameof(ownedNavigationBuilder)); - - InternalCheckConstraintBuilder.HasCheckConstraint( - (IConventionEntityType)ownedNavigationBuilder.OwnedEntityType, - name, - sql, - ConfigurationSource.Explicit); - - return ownedNavigationBuilder; - } - - /// - /// Configures a database check constraint when targeting a relational database. - /// - /// The entity type owning the relationship. - /// The dependent entity type of the relationship. - /// The navigation builder for the owned type. - /// The name of the check constraint. - /// The logical constraint sql used in the check constraint. - /// A builder to further configure the navigation. - public static OwnedNavigationBuilder HasCheckConstraint( - this OwnedNavigationBuilder ownedNavigationBuilder, - string name, - string? sql) - where TEntity : class - where TDependentEntity : class - => (OwnedNavigationBuilder) - HasCheckConstraint((OwnedNavigationBuilder)ownedNavigationBuilder, name, sql); - - /// - /// Configures a database check constraint when targeting a relational database. - /// - /// The navigation builder for the owned type. - /// The name of the check constraint. - /// The logical constraint sql used in the check constraint. - /// An action that performs configuration of the check constraint. - /// A builder to further configure the navigation. - public static OwnedNavigationBuilder HasCheckConstraint( - this OwnedNavigationBuilder ownedNavigationBuilder, - string name, - string sql, - Action buildAction) - { - Check.NotEmpty(sql, nameof(sql)); - Check.NotNull(buildAction, nameof(buildAction)); - - ownedNavigationBuilder.HasCheckConstraint(name, sql); - - buildAction(new CheckConstraintBuilder(ownedNavigationBuilder.OwnedEntityType.FindCheckConstraint(name)!)); - - return ownedNavigationBuilder; - } - - /// - /// Configures a database check constraint when targeting a relational database. - /// - /// The entity type owning the relationship. - /// The dependent entity type of the relationship. - /// The navigation builder for the owned type. - /// The name of the check constraint. - /// The logical constraint sql used in the check constraint. - /// An action that performs configuration of the check constraint. - /// A builder to further configure the navigation. - public static OwnedNavigationBuilder HasCheckConstraint( - this OwnedNavigationBuilder ownedNavigationBuilder, - string name, - string sql, - Action buildAction) - where TEntity : class - where TDependentEntity : class - => (OwnedNavigationBuilder) - HasCheckConstraint((OwnedNavigationBuilder)ownedNavigationBuilder, name, sql, buildAction); - } -} diff --git a/src/EFCore.Relational/Metadata/Builders/TableBuilder.cs b/src/EFCore.Relational/Metadata/Builders/TableBuilder.cs index 62edd527527..0bd920c7bb8 100644 --- a/src/EFCore.Relational/Metadata/Builders/TableBuilder.cs +++ b/src/EFCore.Relational/Metadata/Builders/TableBuilder.cs @@ -21,15 +21,15 @@ public class TableBuilder /// doing so can result in application failures when updating to a new Entity Framework Core release. /// [EntityFrameworkInternal] - public TableBuilder(string? name, string? schema, EntityTypeBuilder entityTypeBuilder) + public TableBuilder(string? name, string? schema, IMutableEntityType entityType) { - EntityTypeBuilder = entityTypeBuilder; + Metadata = entityType; } /// - /// The entity type builder for the entity being configured. + /// The entity type being configured. /// - public virtual EntityTypeBuilder EntityTypeBuilder { get; } + public virtual IMutableEntityType Metadata { get; } /// /// Configures the table to be ignored by migrations. @@ -38,7 +38,7 @@ public TableBuilder(string? name, string? schema, EntityTypeBuilder entityTypeBu /// The same builder instance so that multiple calls can be chained. public virtual TableBuilder ExcludeFromMigrations(bool excluded = true) { - EntityTypeBuilder.Metadata.SetIsTableExcludedFromMigrations(excluded); + Metadata.SetIsTableExcludedFromMigrations(excluded); return this; } diff --git a/src/EFCore.Relational/Metadata/Builders/TableBuilder`.cs b/src/EFCore.Relational/Metadata/Builders/TableBuilder`.cs index 627c4ad05bd..be8f8317cb7 100644 --- a/src/EFCore.Relational/Metadata/Builders/TableBuilder`.cs +++ b/src/EFCore.Relational/Metadata/Builders/TableBuilder`.cs @@ -1,7 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Diagnostics; using Microsoft.EntityFrameworkCore.Infrastructure; namespace Microsoft.EntityFrameworkCore.Metadata.Builders @@ -23,19 +22,11 @@ public class TableBuilder : TableBuilder /// doing so can result in application failures when updating to a new Entity Framework Core release. /// [EntityFrameworkInternal] - public TableBuilder(string? name, string? schema, EntityTypeBuilder entityTypeBuilder) - : base(name, schema, entityTypeBuilder) + public TableBuilder(string? name, string? schema, IMutableEntityType entityType) + : base(name, schema, entityType) { } - /// - /// The entity type builder for the entity being configured. - /// - public new virtual EntityTypeBuilder EntityTypeBuilder - { - [DebuggerStepThrough] get => (EntityTypeBuilder)base.EntityTypeBuilder; - } - /// /// Configures the table to be ignored by migrations. /// diff --git a/src/EFCore.SqlServer/Extensions/SqlServerTableBuilderExtensions.cs b/src/EFCore.SqlServer/Extensions/SqlServerTableBuilderExtensions.cs index 5490e1332bc..bcd3f485dbd 100644 --- a/src/EFCore.SqlServer/Extensions/SqlServerTableBuilderExtensions.cs +++ b/src/EFCore.SqlServer/Extensions/SqlServerTableBuilderExtensions.cs @@ -1,7 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System; using Microsoft.EntityFrameworkCore.Metadata.Builders; // ReSharper disable once CheckNamespace @@ -22,9 +21,9 @@ public static TemporalTableBuilder IsTemporal( this TableBuilder tableBuilder, bool temporal = true) { - tableBuilder.EntityTypeBuilder.Metadata.SetIsTemporal(temporal); + tableBuilder.Metadata.SetIsTemporal(temporal); - return new TemporalTableBuilder(tableBuilder.EntityTypeBuilder); + return new TemporalTableBuilder(tableBuilder.Metadata); } /// @@ -37,8 +36,9 @@ public static TableBuilder IsTemporal( this TableBuilder tableBuilder, Action buildAction) { - tableBuilder.EntityTypeBuilder.Metadata.SetIsTemporal(true); - buildAction(new TemporalTableBuilder(tableBuilder.EntityTypeBuilder)); + tableBuilder.Metadata.SetIsTemporal(true); + + buildAction(new TemporalTableBuilder(tableBuilder.Metadata)); return tableBuilder; } @@ -55,9 +55,9 @@ public static TemporalTableBuilder IsTemporal( bool temporal = true) where TEntity : class { - tableBuilder.EntityTypeBuilder.Metadata.SetIsTemporal(temporal); + tableBuilder.Metadata.SetIsTemporal(temporal); - return new TemporalTableBuilder(tableBuilder.EntityTypeBuilder); + return new TemporalTableBuilder(tableBuilder.Metadata); } /// @@ -72,8 +72,8 @@ public static TableBuilder IsTemporal( Action> buildAction) where TEntity: class { - tableBuilder.EntityTypeBuilder.Metadata.SetIsTemporal(true); - buildAction(new TemporalTableBuilder(tableBuilder.EntityTypeBuilder)); + tableBuilder.Metadata.SetIsTemporal(true); + buildAction(new TemporalTableBuilder(tableBuilder.Metadata)); return tableBuilder; } diff --git a/src/EFCore.SqlServer/Metadata/Builders/TemporalPeriodPropertyBuilder.cs b/src/EFCore.SqlServer/Metadata/Builders/TemporalPeriodPropertyBuilder.cs index b082c27b8d1..cb4103146eb 100644 --- a/src/EFCore.SqlServer/Metadata/Builders/TemporalPeriodPropertyBuilder.cs +++ b/src/EFCore.SqlServer/Metadata/Builders/TemporalPeriodPropertyBuilder.cs @@ -14,7 +14,7 @@ namespace Microsoft.EntityFrameworkCore.Metadata.Builders /// public class TemporalPeriodPropertyBuilder { - private readonly EntityTypeBuilder _entityTypeBuilder; + private readonly IMutableEntityType _entityType; private readonly string _periodPropertyName; /// @@ -24,9 +24,9 @@ public class TemporalPeriodPropertyBuilder /// doing so can result in application failures when updating to a new Entity Framework Core release. /// [EntityFrameworkInternal] - public TemporalPeriodPropertyBuilder(EntityTypeBuilder entityTypeBuilder, string periodPropertyName) + public TemporalPeriodPropertyBuilder(IMutableEntityType entityType, string periodPropertyName) { - _entityTypeBuilder = entityTypeBuilder; + _entityType = entityType; _periodPropertyName = periodPropertyName; } @@ -37,7 +37,7 @@ public TemporalPeriodPropertyBuilder(EntityTypeBuilder entityTypeBuilder, string /// The same builder instance so that multiple calls can be chained. public virtual TemporalPeriodPropertyBuilder HasColumnName(string name) { - _entityTypeBuilder.Metadata.GetProperty(_periodPropertyName).SetColumnName(name); + _entityType.GetProperty(_periodPropertyName).SetColumnName(name); return this; } diff --git a/src/EFCore.SqlServer/Metadata/Builders/TemporalTableBuilder.cs b/src/EFCore.SqlServer/Metadata/Builders/TemporalTableBuilder.cs index 6ef3f6cedd5..f4dfa24d717 100644 --- a/src/EFCore.SqlServer/Metadata/Builders/TemporalTableBuilder.cs +++ b/src/EFCore.SqlServer/Metadata/Builders/TemporalTableBuilder.cs @@ -14,7 +14,7 @@ namespace Microsoft.EntityFrameworkCore.Metadata.Builders /// public class TemporalTableBuilder { - private readonly EntityTypeBuilder _entityTypeBuilder; + private readonly IMutableEntityType _entityType; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -23,9 +23,9 @@ public class TemporalTableBuilder /// doing so can result in application failures when updating to a new Entity Framework Core release. /// [EntityFrameworkInternal] - public TemporalTableBuilder(EntityTypeBuilder entityTypeBuilder) + public TemporalTableBuilder(IMutableEntityType entityType) { - _entityTypeBuilder = entityTypeBuilder; + _entityType = entityType; } /// @@ -35,7 +35,7 @@ public TemporalTableBuilder(EntityTypeBuilder entityTypeBuilder) /// The same builder instance so that multiple calls can be chained. public virtual TemporalTableBuilder WithHistoryTable(string name) { - _entityTypeBuilder.Metadata.SetTemporalHistoryTableName(name); + _entityType.SetTemporalHistoryTableName(name); return this; } @@ -48,8 +48,8 @@ public virtual TemporalTableBuilder WithHistoryTable(string name) /// The same builder instance so that multiple calls can be chained. public virtual TemporalTableBuilder WithHistoryTable(string name, string? schema) { - _entityTypeBuilder.Metadata.SetTemporalHistoryTableName(name); - _entityTypeBuilder.Metadata.SetTemporalHistoryTableSchema(schema); + _entityType.SetTemporalHistoryTableName(name); + _entityType.SetTemporalHistoryTableSchema(schema); return this; } @@ -61,9 +61,9 @@ public virtual TemporalTableBuilder WithHistoryTable(string name, string? schema /// An object that can be used to configure the period start property. public virtual TemporalPeriodPropertyBuilder HasPeriodStart(string propertyName) { - _entityTypeBuilder.Metadata.SetTemporalPeriodStartPropertyName(propertyName); + _entityType.SetTemporalPeriodStartPropertyName(propertyName); - return new TemporalPeriodPropertyBuilder(_entityTypeBuilder, propertyName); + return new TemporalPeriodPropertyBuilder(_entityType, propertyName); } /// @@ -73,9 +73,9 @@ public virtual TemporalPeriodPropertyBuilder HasPeriodStart(string propertyName) /// An object that can be used to configure the period end property. public virtual TemporalPeriodPropertyBuilder HasPeriodEnd(string propertyName) { - _entityTypeBuilder.Metadata.SetTemporalPeriodEndPropertyName(propertyName); + _entityType.SetTemporalPeriodEndPropertyName(propertyName); - return new TemporalPeriodPropertyBuilder(_entityTypeBuilder, propertyName); + return new TemporalPeriodPropertyBuilder(_entityType, propertyName); } #region Hidden System.Object members diff --git a/src/EFCore.SqlServer/Metadata/Builders/TemporalTableBuilder`.cs b/src/EFCore.SqlServer/Metadata/Builders/TemporalTableBuilder`.cs index f6ce7e02c53..3e05c10fcfc 100644 --- a/src/EFCore.SqlServer/Metadata/Builders/TemporalTableBuilder`.cs +++ b/src/EFCore.SqlServer/Metadata/Builders/TemporalTableBuilder`.cs @@ -22,8 +22,8 @@ public class TemporalTableBuilder : TemporalTableBuilder /// doing so can result in application failures when updating to a new Entity Framework Core release. /// [EntityFrameworkInternal] - public TemporalTableBuilder(EntityTypeBuilder entityTypeBuilder) - : base(entityTypeBuilder) + public TemporalTableBuilder(IMutableEntityType entityType) + : base(entityType) { } diff --git a/src/EFCore/Infrastructure/IndentedStringBuilder.cs b/src/EFCore/Infrastructure/IndentedStringBuilder.cs index 3343b16e5fb..27502675cd5 100644 --- a/src/EFCore/Infrastructure/IndentedStringBuilder.cs +++ b/src/EFCore/Infrastructure/IndentedStringBuilder.cs @@ -133,7 +133,7 @@ public virtual IndentedStringBuilder AppendLine(string value) /// by the current indent and followed by a new line, to the string being built. /// /// The string to append. - /// If true, then the terminating new line is not added after the last line. + /// If , then the terminating new line is not added after the last line. /// This builder so that additional calls can be chained. public virtual IndentedStringBuilder AppendLines(string value, bool skipFinalNewline = false) { diff --git a/src/EFCore/Metadata/Builders/OwnedNavigationBuilder`.cs b/src/EFCore/Metadata/Builders/OwnedNavigationBuilder`.cs index a069924eb45..79bb109243e 100644 --- a/src/EFCore/Metadata/Builders/OwnedNavigationBuilder`.cs +++ b/src/EFCore/Metadata/Builders/OwnedNavigationBuilder`.cs @@ -1,8 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System; -using System.Collections.Generic; using System.Linq.Expressions; using System.Reflection; using Microsoft.EntityFrameworkCore.ChangeTracking; @@ -15,8 +13,8 @@ namespace Microsoft.EntityFrameworkCore.Metadata.Builders /// /// Provides a simple API for configuring a navigation to an owned entity type. /// - public class OwnedNavigationBuilder : OwnedNavigationBuilder - where TEntity : class + public class OwnedNavigationBuilder : OwnedNavigationBuilder + where TOwnerEntity : class where TDependentEntity : class { /// @@ -38,10 +36,10 @@ public OwnedNavigationBuilder(IMutableForeignKey ownership) /// The key of the annotation to be added or updated. /// The value to be stored in the annotation. /// The same builder instance so that multiple configuration calls can be chained. - public new virtual OwnedNavigationBuilder HasAnnotation( + public new virtual OwnedNavigationBuilder HasAnnotation( string annotation, object? value) - => (OwnedNavigationBuilder)base.HasAnnotation(annotation, value); + => (OwnedNavigationBuilder)base.HasAnnotation(annotation, value); /// /// Sets the properties that make up the primary key for this owned entity type. @@ -143,8 +141,8 @@ public virtual NavigationBuilder Navigation /// The name of the property to be removed from the entity type. - public new virtual OwnedNavigationBuilder Ignore(string propertyName) - => (OwnedNavigationBuilder)base.Ignore(propertyName); + public new virtual OwnedNavigationBuilder Ignore(string propertyName) + => (OwnedNavigationBuilder)base.Ignore(propertyName); /// /// Excludes the given property from the entity type. This method is typically used to remove properties @@ -154,9 +152,9 @@ public virtual NavigationBuilder Navigationblog => blog.Url). /// - public virtual OwnedNavigationBuilder Ignore( + public virtual OwnedNavigationBuilder Ignore( Expression> propertyExpression) - => (OwnedNavigationBuilder) + => (OwnedNavigationBuilder) base.Ignore( Check.NotNull(propertyExpression, nameof(propertyExpression)) .GetMemberAccess().GetSimpleMemberName()); @@ -208,12 +206,12 @@ public virtual IndexBuilder HasIndex(Expression /// An object that can be used to configure the relationship. - public new virtual OwnershipBuilder WithOwner( + public new virtual OwnershipBuilder WithOwner( string? ownerReference = null) { Check.NullButNotEmpty(ownerReference, nameof(ownerReference)); - return new OwnershipBuilder( + return new OwnershipBuilder( PrincipalEntityType, DependentEntityType, Builder.HasNavigation( @@ -238,8 +236,8 @@ public virtual IndexBuilder HasIndex(Expression /// An object that can be used to configure the relationship. - public virtual OwnershipBuilder WithOwner( - Expression>? referenceExpression) + public virtual OwnershipBuilder WithOwner( + Expression>? referenceExpression) => new( PrincipalEntityType, DependentEntityType, @@ -398,7 +396,7 @@ public virtual OwnedNavigationBuilder Own /// /// An action that performs configuration of the relationship. /// An object that can be used to configure the entity type. - public virtual OwnedNavigationBuilder OwnsOne( + public virtual OwnedNavigationBuilder OwnsOne( string navigationName, Action> buildAction) where TNewDependentEntity : class @@ -437,11 +435,11 @@ public virtual OwnedNavigationBuilder OwnsOne /// An action that performs configuration of the relationship. /// An object that can be used to configure the entity type. - public new virtual OwnedNavigationBuilder OwnsOne( + public new virtual OwnedNavigationBuilder OwnsOne( string ownedTypeName, string navigationName, Action buildAction) - => (OwnedNavigationBuilder)base.OwnsOne(ownedTypeName, navigationName, buildAction); + => (OwnedNavigationBuilder)base.OwnsOne(ownedTypeName, navigationName, buildAction); /// /// @@ -468,12 +466,12 @@ public virtual OwnedNavigationBuilder OwnsOne /// An action that performs configuration of the relationship. /// An object that can be used to configure the entity type. - public new virtual OwnedNavigationBuilder OwnsOne( + public new virtual OwnedNavigationBuilder OwnsOne( string ownedTypeName, Type ownedType, string navigationName, Action buildAction) - => (OwnedNavigationBuilder)base.OwnsOne(ownedTypeName, ownedType, navigationName, buildAction); + => (OwnedNavigationBuilder)base.OwnsOne(ownedTypeName, ownedType, navigationName, buildAction); /// /// @@ -499,11 +497,11 @@ public virtual OwnedNavigationBuilder OwnsOne /// An action that performs configuration of the relationship. /// An object that can be used to configure the entity type. - public new virtual OwnedNavigationBuilder OwnsOne( + public new virtual OwnedNavigationBuilder OwnsOne( Type ownedType, string navigationName, Action buildAction) - => (OwnedNavigationBuilder)base.OwnsOne(ownedType, navigationName, buildAction); + => (OwnedNavigationBuilder)base.OwnsOne(ownedType, navigationName, buildAction); /// /// @@ -530,7 +528,7 @@ public virtual OwnedNavigationBuilder OwnsOne /// An action that performs configuration of the relationship. /// An object that can be used to configure the entity type. - public virtual OwnedNavigationBuilder OwnsOne( + public virtual OwnedNavigationBuilder OwnsOne( string ownedTypeName, string navigationName, Action> buildAction) @@ -571,7 +569,7 @@ public virtual OwnedNavigationBuilder OwnsOne /// An action that performs configuration of the relationship. /// An object that can be used to configure the entity type. - public virtual OwnedNavigationBuilder OwnsOne( + public virtual OwnedNavigationBuilder OwnsOne( Expression> navigationExpression, Action> buildAction) where TNewDependentEntity : class @@ -612,7 +610,7 @@ public virtual OwnedNavigationBuilder OwnsOne /// An action that performs configuration of the relationship. /// An object that can be used to configure the entity type. - public virtual OwnedNavigationBuilder OwnsOne( + public virtual OwnedNavigationBuilder OwnsOne( string ownedTypeName, Expression> navigationExpression, Action> buildAction) @@ -790,7 +788,7 @@ public virtual OwnedNavigationBuilder Own /// /// An action that performs configuration of the owned type and the relationship. /// An object that can be used to configure the entity type. - public virtual OwnedNavigationBuilder OwnsMany( + public virtual OwnedNavigationBuilder OwnsMany( string navigationName, Action> buildAction) where TNewDependentEntity : class @@ -831,11 +829,11 @@ public virtual OwnedNavigationBuilder OwnsMany /// An action that performs configuration of the owned type and the relationship. /// An object that can be used to configure the entity type. - public new virtual OwnedNavigationBuilder OwnsMany( + public new virtual OwnedNavigationBuilder OwnsMany( string ownedTypeName, string navigationName, Action buildAction) - => (OwnedNavigationBuilder)base.OwnsMany(ownedTypeName, navigationName, buildAction); + => (OwnedNavigationBuilder)base.OwnsMany(ownedTypeName, navigationName, buildAction); /// /// @@ -860,11 +858,11 @@ public virtual OwnedNavigationBuilder OwnsMany /// An action that performs configuration of the owned type and the relationship. /// An object that can be used to configure the entity type. - public new virtual OwnedNavigationBuilder OwnsMany( + public new virtual OwnedNavigationBuilder OwnsMany( Type ownedType, string navigationName, Action buildAction) - => (OwnedNavigationBuilder)base.OwnsMany(ownedType, navigationName, buildAction); + => (OwnedNavigationBuilder)base.OwnsMany(ownedType, navigationName, buildAction); /// /// @@ -890,12 +888,12 @@ public virtual OwnedNavigationBuilder OwnsMany /// An action that performs configuration of the owned type and the relationship. /// An object that can be used to configure the entity type. - public new virtual OwnedNavigationBuilder OwnsMany( + public new virtual OwnedNavigationBuilder OwnsMany( string ownedTypeName, Type ownedType, string navigationName, Action buildAction) - => (OwnedNavigationBuilder)base.OwnsMany(ownedTypeName, ownedType, navigationName, buildAction); + => (OwnedNavigationBuilder)base.OwnsMany(ownedTypeName, ownedType, navigationName, buildAction); /// /// @@ -921,7 +919,7 @@ public virtual OwnedNavigationBuilder OwnsMany /// An action that performs configuration of the owned type and the relationship. /// An object that can be used to configure the entity type. - public virtual OwnedNavigationBuilder OwnsMany( + public virtual OwnedNavigationBuilder OwnsMany( string ownedTypeName, string navigationName, Action> buildAction) @@ -964,7 +962,7 @@ public virtual OwnedNavigationBuilder OwnsMany /// An action that performs configuration of the owned type and the relationship. /// An object that can be used to configure the entity type. - public virtual OwnedNavigationBuilder OwnsMany( + public virtual OwnedNavigationBuilder OwnsMany( Expression?>> navigationExpression, Action> buildAction) where TNewDependentEntity : class @@ -1007,7 +1005,7 @@ public virtual OwnedNavigationBuilder OwnsMany /// An action that performs configuration of the owned type and the relationship. /// An object that can be used to configure the entity type. - public virtual OwnedNavigationBuilder OwnsMany( + public virtual OwnedNavigationBuilder OwnsMany( string ownedTypeName, Expression?>> navigationExpression, Action> buildAction) @@ -1134,9 +1132,9 @@ public virtual ReferenceNavigationBuilder H /// /// The change tracking strategy to be used. /// The same builder instance so that multiple configuration calls can be chained. - public new virtual OwnedNavigationBuilder HasChangeTrackingStrategy( + public new virtual OwnedNavigationBuilder HasChangeTrackingStrategy( ChangeTrackingStrategy changeTrackingStrategy) - => (OwnedNavigationBuilder)base.HasChangeTrackingStrategy(changeTrackingStrategy); + => (OwnedNavigationBuilder)base.HasChangeTrackingStrategy(changeTrackingStrategy); /// /// @@ -1155,8 +1153,8 @@ public virtual ReferenceNavigationBuilder H /// /// The to use for properties of this entity type. /// The same builder instance so that multiple configuration calls can be chained. - public new virtual OwnedNavigationBuilder UsePropertyAccessMode(PropertyAccessMode propertyAccessMode) - => (OwnedNavigationBuilder)base.UsePropertyAccessMode(propertyAccessMode); + public new virtual OwnedNavigationBuilder UsePropertyAccessMode(PropertyAccessMode propertyAccessMode) + => (OwnedNavigationBuilder)base.UsePropertyAccessMode(propertyAccessMode); /// /// Adds seed data to this entity type. It is used to generate data motion migrations. diff --git a/test/EFCore.Design.Tests/Migrations/ModelSnapshotSqlServerTest.cs b/test/EFCore.Design.Tests/Migrations/ModelSnapshotSqlServerTest.cs index 32853950619..c37558323fe 100644 --- a/test/EFCore.Design.Tests/Migrations/ModelSnapshotSqlServerTest.cs +++ b/test/EFCore.Design.Tests/Migrations/ModelSnapshotSqlServerTest.cs @@ -544,7 +544,7 @@ public void TVF_types_are_stored_in_the_model_snapshot() => Test( b.Property(""Something"") .HasColumnType(""nvarchar(max)""); - b.ToTable(null, (string)null); + b.ToTable((string)null); });"), o => { @@ -1859,12 +1859,12 @@ public virtual void Temporal_table_information_is_stored_in_snapshot() b .ToTable(tb => tb.IsTemporal(ttb => -{ - ttb.WithHistoryTable(""HistoryTable""); - ttb.HasPeriodStart(""Start"").HasColumnName(""PeriodStart""); - ttb.HasPeriodEnd(""End"").HasColumnName(""PeriodEnd""); -} -)); + { + ttb.WithHistoryTable(""HistoryTable""); + ttb.HasPeriodStart(""Start"").HasColumnName(""PeriodStart""); + ttb.HasPeriodEnd(""End"").HasColumnName(""PeriodEnd""); + } + )); });", usingSystem: true), o => { @@ -2142,7 +2142,7 @@ public virtual void Owned_types_are_stored_in_snapshot_when_excluded() es.HasKey(e => e.Id); es.HasOne(e => e.EntityWithOneProperty).WithOne(); - es.ToTable("EntityWithStringProperty", excludedFromMigrations: true); + es.ToTable("EntityWithStringProperty", t => t.ExcludeFromMigrations()); }); b.ToTable("EntityWithStringKey", e => e.ExcludeFromMigrations()); @@ -2254,7 +2254,7 @@ public virtual void Owned_types_are_stored_in_snapshot_when_excluded() b1.HasIndex(""EntityWithStringKeyId""); - b1.ToTable(""EntityWithStringProperty"", null, excludedFromMigrations: true); + b1.ToTable(""EntityWithStringProperty"", null, t => t.ExcludeFromMigrations()); b1.HasOne(""Microsoft.EntityFrameworkCore.Migrations.ModelSnapshotSqlServerTest+EntityWithOneProperty"", ""EntityWithOneProperty"") .WithOne() diff --git a/test/EFCore.Design.Tests/Scaffolding/Internal/CSharpRuntimeModelCodeGeneratorTest.cs b/test/EFCore.Design.Tests/Scaffolding/Internal/CSharpRuntimeModelCodeGeneratorTest.cs index 4169357d8ce..cd735d3a1d4 100644 --- a/test/EFCore.Design.Tests/Scaffolding/Internal/CSharpRuntimeModelCodeGeneratorTest.cs +++ b/test/EFCore.Design.Tests/Scaffolding/Internal/CSharpRuntimeModelCodeGeneratorTest.cs @@ -1717,7 +1717,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) eb.OwnsMany(typeof(OwnedType).FullName, "ManyOwned", ob => { ob.IsMemoryOptimized(); - ob.ToTable("ManyOwned", excludedFromMigrations: true); + ob.ToTable("ManyOwned", t => t.ExcludeFromMigrations()); }); eb.HasMany(e => e.Principals).WithMany(e => (ICollection>>)e.Deriveds) diff --git a/test/EFCore.Relational.Tests/Migrations/Internal/MigrationsModelDifferTest.cs b/test/EFCore.Relational.Tests/Migrations/Internal/MigrationsModelDifferTest.cs index f254bf9bda6..2c33f329f44 100644 --- a/test/EFCore.Relational.Tests/Migrations/Internal/MigrationsModelDifferTest.cs +++ b/test/EFCore.Relational.Tests/Migrations/Internal/MigrationsModelDifferTest.cs @@ -9822,7 +9822,7 @@ public void SeedData_type_with_excluded_owned_collection() c.OwnsMany( y => y.Orders, x => { - x.ToTable("Order", excludedFromMigrations: true); + x.ToTable("Order", t => t.ExcludeFromMigrations()); }); c.ToTable("Customer", t => t.ExcludeFromMigrations()); }); diff --git a/test/EFCore.Relational.Tests/ModelBuilding/RelationalTestModelBuilderExtensions.cs b/test/EFCore.Relational.Tests/ModelBuilding/RelationalTestModelBuilderExtensions.cs index a091ba56253..e5550344414 100644 --- a/test/EFCore.Relational.Tests/ModelBuilding/RelationalTestModelBuilderExtensions.cs +++ b/test/EFCore.Relational.Tests/ModelBuilding/RelationalTestModelBuilderExtensions.cs @@ -115,7 +115,7 @@ public static ModelBuilderTest.TestPropertyBuilder IsFixedLength ToTable( this ModelBuilderTest.TestEntityTypeBuilder builder, - string name) + string? name) where TEntity : class { switch (builder) @@ -134,7 +134,7 @@ public static ModelBuilderTest.TestEntityTypeBuilder ToTable( public static ModelBuilderTest.TestEntityTypeBuilder ToTable( this ModelBuilderTest.TestEntityTypeBuilder builder, string name, - string schema) + string? schema) where TEntity : class { switch (builder) @@ -152,7 +152,7 @@ public static ModelBuilderTest.TestEntityTypeBuilder ToTable( public static ModelBuilderTest.TestEntityTypeBuilder ToTable( this ModelBuilderTest.TestEntityTypeBuilder builder, - string name, + string? name, Action> buildAction) where TEntity : class { @@ -174,7 +174,7 @@ public static ModelBuilderTest.TestEntityTypeBuilder ToTable( public static ModelBuilderTest.TestEntityTypeBuilder ToTable( this ModelBuilderTest.TestEntityTypeBuilder builder, string name, - string schema, + string? schema, Action> buildAction) where TEntity : class { @@ -193,15 +193,15 @@ public static ModelBuilderTest.TestEntityTypeBuilder ToTable( return builder; } - public static ModelBuilderTest.TestOwnedNavigationBuilder ToTable( - this ModelBuilderTest.TestOwnedNavigationBuilder builder, - string name) - where TEntity : class + public static ModelBuilderTest.TestOwnedNavigationBuilder ToTable( + this ModelBuilderTest.TestOwnedNavigationBuilder builder, + string? name) + where TOwnerEntity : class where TRelatedEntity : class { switch (builder) { - case IInfrastructure> genericBuilder: + case IInfrastructure> genericBuilder: genericBuilder.Instance.ToTable(name); break; case IInfrastructure nongenericBuilder: @@ -212,16 +212,16 @@ public static ModelBuilderTest.TestOwnedNavigationBuilder ToTable( - this ModelBuilderTest.TestOwnedNavigationBuilder builder, + public static ModelBuilderTest.TestOwnedNavigationBuilder ToTable( + this ModelBuilderTest.TestOwnedNavigationBuilder builder, string name, - string schema) - where TEntity : class + string? schema) + where TOwnerEntity : class where TRelatedEntity : class { switch (builder) { - case IInfrastructure> genericBuilder: + case IInfrastructure> genericBuilder: genericBuilder.Instance.ToTable(name, schema); break; case IInfrastructure nongenericBuilder: @@ -232,41 +232,45 @@ public static ModelBuilderTest.TestOwnedNavigationBuilder ToTable( - this ModelBuilderTest.TestOwnedNavigationBuilder builder, - string name, - bool excludedFromMigrations) - where TEntity : class + public static ModelBuilderTest.TestOwnedNavigationBuilder ToTable( + this ModelBuilderTest.TestOwnedNavigationBuilder builder, + string? name, + Action> buildAction) + where TOwnerEntity : class where TRelatedEntity : class { switch (builder) { - case IInfrastructure> genericBuilder: - genericBuilder.Instance.ToTable(name, excludedFromMigrations); + case IInfrastructure> genericBuilder: + genericBuilder.Instance.ToTable(name, + b => buildAction(new RelationalModelBuilderTest.GenericTestTableBuilder(b))); break; case IInfrastructure nongenericBuilder: - nongenericBuilder.Instance.ToTable(name, excludedFromMigrations); + nongenericBuilder.Instance.ToTable(name, + b => buildAction(new RelationalModelBuilderTest.NonGenericTestTableBuilder(b))); break; } return builder; } - public static ModelBuilderTest.TestOwnedNavigationBuilder ToTable( - this ModelBuilderTest.TestOwnedNavigationBuilder builder, + public static ModelBuilderTest.TestOwnedNavigationBuilder ToTable( + this ModelBuilderTest.TestOwnedNavigationBuilder builder, string name, - string schema, - bool excludedFromMigrations) - where TEntity : class + string? schema, + Action> buildAction) + where TOwnerEntity : class where TRelatedEntity : class { switch (builder) { - case IInfrastructure> genericBuilder: - genericBuilder.Instance.ToTable(name, schema, excludedFromMigrations); + case IInfrastructure> genericBuilder: + genericBuilder.Instance.ToTable(name, schema, + b => buildAction(new RelationalModelBuilderTest.GenericTestTableBuilder(b))); break; case IInfrastructure nongenericBuilder: - nongenericBuilder.Instance.ToTable(name, schema, excludedFromMigrations); + nongenericBuilder.Instance.ToTable(name, schema, + b => buildAction(new RelationalModelBuilderTest.NonGenericTestTableBuilder(b))); break; } @@ -314,16 +318,16 @@ public static ModelBuilderTest.TestEntityTypeBuilder HasCheckConstraint return builder; } - public static ModelBuilderTest.TestOwnedNavigationBuilder HasCheckConstraint( - this ModelBuilderTest.TestOwnedNavigationBuilder builder, + public static ModelBuilderTest.TestOwnedNavigationBuilder HasCheckConstraint( + this ModelBuilderTest.TestOwnedNavigationBuilder builder, string name, string? sql) - where TEntity : class + where TOwnerEntity : class where TRelatedEntity : class { switch (builder) { - case IInfrastructure> genericBuilder: + case IInfrastructure> genericBuilder: genericBuilder.Instance.HasCheckConstraint(name, sql); break; case IInfrastructure nongenericBuilder: @@ -334,17 +338,17 @@ public static ModelBuilderTest.TestOwnedNavigationBuilder HasCheckConstraint( - this ModelBuilderTest.TestOwnedNavigationBuilder builder, + public static ModelBuilderTest.TestOwnedNavigationBuilder HasCheckConstraint( + this ModelBuilderTest.TestOwnedNavigationBuilder builder, string name, string sql, Action buildAction) - where TEntity : class + where TOwnerEntity : class where TRelatedEntity : class { switch (builder) { - case IInfrastructure> genericBuilder: + case IInfrastructure> genericBuilder: genericBuilder.Instance.HasCheckConstraint(name, sql, b => buildAction(new RelationalModelBuilderTest.NonGenericTestCheckConstraintBuilder(b))); break; @@ -357,15 +361,15 @@ public static ModelBuilderTest.TestOwnedNavigationBuilder HasConstraintName( - this ModelBuilderTest.TestOwnershipBuilder builder, + public static ModelBuilderTest.TestOwnershipBuilder HasConstraintName( + this ModelBuilderTest.TestOwnershipBuilder builder, string name) - where TEntity : class + where TOwnerEntity : class where TRelatedEntity : class { switch (builder) { - case IInfrastructure> genericBuilder: + case IInfrastructure> genericBuilder: genericBuilder.Instance.HasConstraintName(name); break; case IInfrastructure nongenericBuilder: @@ -376,15 +380,15 @@ public static ModelBuilderTest.TestOwnershipBuilder Has return builder; } - public static ModelBuilderTest.TestReferenceReferenceBuilder HasConstraintName( - this ModelBuilderTest.TestReferenceReferenceBuilder builder, + public static ModelBuilderTest.TestReferenceReferenceBuilder HasConstraintName( + this ModelBuilderTest.TestReferenceReferenceBuilder builder, string name) - where TEntity : class + where TOwnerEntity : class where TRelatedEntity : class { switch (builder) { - case IInfrastructure> genericBuilder: + case IInfrastructure> genericBuilder: genericBuilder.Instance.HasConstraintName(name); break; case IInfrastructure nongenericBuilder: @@ -395,15 +399,15 @@ public static ModelBuilderTest.TestReferenceReferenceBuilder HasConstraintName( - this ModelBuilderTest.TestReferenceCollectionBuilder builder, + public static ModelBuilderTest.TestReferenceCollectionBuilder HasConstraintName( + this ModelBuilderTest.TestReferenceCollectionBuilder builder, string name) - where TEntity : class + where TOwnerEntity : class where TRelatedEntity : class { switch (builder) { - case IInfrastructure> genericBuilder: + case IInfrastructure> genericBuilder: genericBuilder.Instance.HasConstraintName(name); break; case IInfrastructure nongenericBuilder: diff --git a/test/EFCore.Relational.Tests/RelationalApiConsistencyTest.cs b/test/EFCore.Relational.Tests/RelationalApiConsistencyTest.cs index f3ee71459a0..40a1a0d5453 100644 --- a/test/EFCore.Relational.Tests/RelationalApiConsistencyTest.cs +++ b/test/EFCore.Relational.Tests/RelationalApiConsistencyTest.cs @@ -197,7 +197,22 @@ public override nameof(RelationalEntityTypeBuilderExtensions.ExcludeTableFromMigrations)), typeof(RelationalEntityTypeBuilderExtensions).GetMethod( nameof(RelationalEntityTypeBuilderExtensions.ToTable), - new Type[] { typeof(EntityTypeBuilder), typeof(Action) }) + new Type[] { typeof(EntityTypeBuilder), typeof(Action) }), + typeof(RelationalEntityTypeBuilderExtensions).GetMethod( + nameof(RelationalEntityTypeBuilderExtensions.ToTable), + new Type[] { typeof(EntityTypeBuilder), typeof(string), typeof(Action) }), + typeof(RelationalEntityTypeBuilderExtensions).GetMethod( + nameof(RelationalEntityTypeBuilderExtensions.ToTable), + new Type[] { typeof(EntityTypeBuilder), typeof(string), typeof(string), typeof(Action) }), + typeof(RelationalEntityTypeBuilderExtensions).GetMethod( + nameof(RelationalEntityTypeBuilderExtensions.ToTable), + new Type[] { typeof(OwnedNavigationBuilder), typeof(Action) }), + typeof(RelationalEntityTypeBuilderExtensions).GetMethod( + nameof(RelationalEntityTypeBuilderExtensions.ToTable), + new Type[] { typeof(OwnedNavigationBuilder), typeof(string), typeof(Action) }), + typeof(RelationalEntityTypeBuilderExtensions).GetMethod( + nameof(RelationalEntityTypeBuilderExtensions.ToTable), + new Type[] { typeof(OwnedNavigationBuilder), typeof(string), typeof(string), typeof(Action) }) }; public override HashSet AsyncMethodExceptions { get; } = new() diff --git a/test/EFCore.Specification.Tests/ApiConsistencyTestBase.cs b/test/EFCore.Specification.Tests/ApiConsistencyTestBase.cs index d464481b7fd..504711a3b09 100644 --- a/test/EFCore.Specification.Tests/ApiConsistencyTestBase.cs +++ b/test/EFCore.Specification.Tests/ApiConsistencyTestBase.cs @@ -1,19 +1,13 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System; -using System.Collections.Generic; -using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; -using System.Threading; -using System.Threading.Tasks; using Microsoft.EntityFrameworkCore.Diagnostics; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Metadata.Builders; using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure; -using Microsoft.EntityFrameworkCore.Metadata.Internal; using Microsoft.EntityFrameworkCore.Query; using Microsoft.Extensions.DependencyInjection; using Xunit; @@ -140,7 +134,7 @@ public void Generic_fluent_api_methods_should_return_generic_types() Assert.False( nonGenericMethods.Count > 0, - "\r\n-- Non-generic fluent returns --\r\n" + "\r\n-- Non-generic fluent returns that aren't hidden --\r\n" + string.Join( Environment.NewLine, nonGenericMethods.Select( m => diff --git a/test/EFCore.SqlServer.Tests/ModelBuilding/SqlServerModelBuilderGenericTest.cs b/test/EFCore.SqlServer.Tests/ModelBuilding/SqlServerModelBuilderGenericTest.cs index e76acdd38b1..a5bf7af82d8 100644 --- a/test/EFCore.SqlServer.Tests/ModelBuilding/SqlServerModelBuilderGenericTest.cs +++ b/test/EFCore.SqlServer.Tests/ModelBuilding/SqlServerModelBuilderGenericTest.cs @@ -609,7 +609,7 @@ public virtual void Owned_types_can_be_mapped_to_different_tables() l => l.AnotherBookLabel, ab => { ab.Ignore(l => l.Book); - ab.ToTable("AT1", "AS1", excludedFromMigrations: false); + ab.ToTable("AT1", "AS1", t => t.ExcludeFromMigrations(false)); ab.OwnsOne(s => s.SpecialBookLabel) .ToTable("ST11", "SS11") .Ignore(l => l.Book)