From 67f08adde5e51dcac464ce7a5a351aca0e60ae06 Mon Sep 17 00:00:00 2001 From: Arthur Vickers Date: Sun, 30 Sep 2018 13:57:11 -0700 Subject: [PATCH] Added a ModelBuilder.FinalizeModel method to support building outside the context Fixes #11738 Naming to be discussed. This runs the model-based conventions and model validation. Also moved setting or product version annotation to any use of the ModelBuilder and then removed from places in the tests that this would cause problems when the version changes. --- .../F1OracleFixture.cs | 8 +++- .../Internal/InMemoryConventionSetBuilder.cs | 22 +++++++++++ .../F1RelationalFixture.cs | 4 +- .../MigrationSqlGeneratorTestBase.cs | 1 + .../DataAnnotationTestBase.cs | 6 +-- .../F1FixtureBase.cs | 24 ++++++++++-- .../OptimisticConcurrencyTestBase.cs | 13 +++++++ .../TestUtilities/TestModelSource.cs | 3 +- src/EFCore/Infrastructure/ModelSource.cs | 3 +- .../Metadata/Conventions/ConventionSet.cs | 12 +++++- .../Internal/ValidatingConvention.cs | 38 +++++++++++++++++++ src/EFCore/ModelBuilder.cs | 18 +++++++++ .../Design/CSharpMigrationsGeneratorTest.cs | 8 ++-- .../Migrations/ModelSnapshotSqlServerTest.cs | 24 ++---------- .../Internal/ModelCodeGeneratorTestBase.cs | 27 ++++++++++++- .../F1InMemoryFixture.cs | 4 ++ .../Internal/MigrationsModelDifferTest.cs | 3 +- .../Internal/MigrationsModelDifferTestBase.cs | 4 +- .../F1SqlServerFixture.cs | 9 +++-- ...erValueGenerationStrategyConventionTest.cs | 4 ++ .../F1SqliteFixture.cs | 4 ++ 21 files changed, 188 insertions(+), 51 deletions(-) create mode 100644 src/EFCore/Metadata/Conventions/Internal/ValidatingConvention.cs diff --git a/samples/OracleProvider/test/OracleProvider.FunctionalTests/F1OracleFixture.cs b/samples/OracleProvider/test/OracleProvider.FunctionalTests/F1OracleFixture.cs index d31be7d8176..98a8d3687de 100644 --- a/samples/OracleProvider/test/OracleProvider.FunctionalTests/F1OracleFixture.cs +++ b/samples/OracleProvider/test/OracleProvider.FunctionalTests/F1OracleFixture.cs @@ -1,6 +1,7 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +using Microsoft.EntityFrameworkCore.Metadata.Conventions; using Microsoft.EntityFrameworkCore.TestModels.ConcurrencyModel; using Microsoft.EntityFrameworkCore.TestUtilities; @@ -10,9 +11,12 @@ public class F1OracleFixture : F1RelationalFixture { protected override ITestStoreFactory TestStoreFactory => OracleTestStoreFactory.Instance; - protected override void OnModelCreating(ModelBuilder modelBuilder, DbContext context) + public override ModelBuilder CreateModelBuilder() + => new ModelBuilder(OracleConventionSetBuilder.Build()); + + protected override void BuildModelExternal(ModelBuilder modelBuilder) { - base.OnModelCreating(modelBuilder, context); + base.BuildModelExternal(modelBuilder); modelBuilder.Entity().Property("Version").IsRowVersion(); modelBuilder.Entity().Property("Version").IsRowVersion(); diff --git a/src/EFCore.InMemory/Metadata/Conventions/Internal/InMemoryConventionSetBuilder.cs b/src/EFCore.InMemory/Metadata/Conventions/Internal/InMemoryConventionSetBuilder.cs index 3a06a8acaea..e1726c853bb 100644 --- a/src/EFCore.InMemory/Metadata/Conventions/Internal/InMemoryConventionSetBuilder.cs +++ b/src/EFCore.InMemory/Metadata/Conventions/Internal/InMemoryConventionSetBuilder.cs @@ -1,8 +1,10 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +using System; using Microsoft.EntityFrameworkCore.Metadata.Conventions; using Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal; +using Microsoft.Extensions.DependencyInjection; namespace Microsoft.EntityFrameworkCore.InMemory.Metadata.Conventions.Internal { @@ -17,5 +19,25 @@ public class InMemoryConventionSetBuilder : IConventionSetBuilder /// directly from your code. This API may change or be removed in future releases. /// public virtual ConventionSet AddConventions(ConventionSet conventionSet) => conventionSet; + + /// + /// This API supports the Entity Framework Core infrastructure and is not intended to be used + /// directly from your code. This API may change or be removed in future releases. + /// + public static ConventionSet Build() + { + var serviceProvider = new ServiceCollection() + .AddEntityFrameworkInMemoryDatabase() + .AddDbContext(o => o.UseInMemoryDatabase(Guid.NewGuid().ToString())) + .BuildServiceProvider(); + + using (var serviceScope = serviceProvider.GetRequiredService().CreateScope()) + { + using (var context = serviceScope.ServiceProvider.GetService()) + { + return ConventionSet.CreateConventionSet(context); + } + } + } } } diff --git a/src/EFCore.Relational.Specification.Tests/F1RelationalFixture.cs b/src/EFCore.Relational.Specification.Tests/F1RelationalFixture.cs index 86f50d9cdec..a143e0e79ed 100644 --- a/src/EFCore.Relational.Specification.Tests/F1RelationalFixture.cs +++ b/src/EFCore.Relational.Specification.Tests/F1RelationalFixture.cs @@ -15,9 +15,9 @@ public override DbContextOptionsBuilder AddOptions(DbContextOptionsBuilder build => base.AddOptions(builder).ConfigureWarnings(w => w.Ignore(RelationalEventId.BatchSmallerThanMinBatchSize)); - protected override void OnModelCreating(ModelBuilder modelBuilder, DbContext context) + protected override void BuildModelExternal(ModelBuilder modelBuilder) { - base.OnModelCreating(modelBuilder, context); + base.BuildModelExternal(modelBuilder); modelBuilder.Entity().ToTable("Chassis"); modelBuilder.Entity().ToTable("Teams").Property(e => e.Id).ValueGeneratedNever(); diff --git a/src/EFCore.Relational.Specification.Tests/MigrationSqlGeneratorTestBase.cs b/src/EFCore.Relational.Specification.Tests/MigrationSqlGeneratorTestBase.cs index e0d789ef8b7..78827c876db 100644 --- a/src/EFCore.Relational.Specification.Tests/MigrationSqlGeneratorTestBase.cs +++ b/src/EFCore.Relational.Specification.Tests/MigrationSqlGeneratorTestBase.cs @@ -725,6 +725,7 @@ protected virtual void Generate(params MigrationOperation[] operation) protected virtual void Generate(Action buildAction, params MigrationOperation[] operation) { var modelBuilder = TestHelpers.CreateConventionBuilder(); + modelBuilder.Model.RemoveAnnotation(CoreAnnotationNames.ProductVersionAnnotation); buildAction(modelBuilder); var batch = TestHelpers.CreateContextServices().GetRequiredService() diff --git a/src/EFCore.Specification.Tests/DataAnnotationTestBase.cs b/src/EFCore.Specification.Tests/DataAnnotationTestBase.cs index fa794ffbc8b..4a2c63f7c81 100644 --- a/src/EFCore.Specification.Tests/DataAnnotationTestBase.cs +++ b/src/EFCore.Specification.Tests/DataAnnotationTestBase.cs @@ -58,11 +58,7 @@ protected virtual IConventionSetBuilder CreateConventionSetBuilder(DbContext con => new CompositeConventionSetBuilder(context.GetService>().ToList()); protected virtual void Validate(ModelBuilder modelBuilder) - { - modelBuilder.GetInfrastructure().Metadata.Validate(); - var context = CreateContext(); - context.GetService().Validate(modelBuilder.Model); - } + => modelBuilder.FinalizeModel(); protected class Person { diff --git a/src/EFCore.Specification.Tests/F1FixtureBase.cs b/src/EFCore.Specification.Tests/F1FixtureBase.cs index 554f4c9df2d..88b5286bb84 100644 --- a/src/EFCore.Specification.Tests/F1FixtureBase.cs +++ b/src/EFCore.Specification.Tests/F1FixtureBase.cs @@ -2,6 +2,7 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using Microsoft.EntityFrameworkCore.Diagnostics; +using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.TestModels.ConcurrencyModel; namespace Microsoft.EntityFrameworkCore @@ -13,13 +14,30 @@ public abstract class F1FixtureBase : SharedStoreFixtureBase protected override bool UsePooling => true; public override DbContextOptionsBuilder AddOptions(DbContextOptionsBuilder builder) - => base.AddOptions(builder).ConfigureWarnings(w => - w.Ignore(CoreEventId.SaveChangesStarting, CoreEventId.SaveChangesCompleted)); + => base.AddOptions(builder) + .UseModel(CreateModelExternal()) + .ConfigureWarnings( + w => w.Ignore(CoreEventId.SaveChangesStarting, CoreEventId.SaveChangesCompleted)); protected override bool ShouldLogCategory(string logCategory) => logCategory == DbLoggerCategory.Update.Name; - protected override void OnModelCreating(ModelBuilder modelBuilder, DbContext context) + private IModel CreateModelExternal() + { + // Doing this differently here from other tests to have regression coverage for + // building models externally from the context instance. + var builder = CreateModelBuilder(); + + BuildModelExternal(builder); + + builder.FinalizeModel(); + + return builder.Model; + } + + public abstract ModelBuilder CreateModelBuilder(); + + protected virtual void BuildModelExternal(ModelBuilder modelBuilder) { modelBuilder.Entity(b => { b.HasKey(c => c.TeamId); }); diff --git a/src/EFCore.Specification.Tests/OptimisticConcurrencyTestBase.cs b/src/EFCore.Specification.Tests/OptimisticConcurrencyTestBase.cs index 3ea23919c01..3d121e59725 100644 --- a/src/EFCore.Specification.Tests/OptimisticConcurrencyTestBase.cs +++ b/src/EFCore.Specification.Tests/OptimisticConcurrencyTestBase.cs @@ -7,6 +7,7 @@ using Microsoft.EntityFrameworkCore.ChangeTracking; using Microsoft.EntityFrameworkCore.Diagnostics; using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Internal; using Microsoft.EntityFrameworkCore.Storage; using Microsoft.EntityFrameworkCore.TestModels.ConcurrencyModel; using Microsoft.EntityFrameworkCore.TestUtilities.Xunit; @@ -28,6 +29,18 @@ protected OptimisticConcurrencyTestBase(TFixture fixture) protected TFixture Fixture { get; } + [Fact] + public virtual void External_model_builder_uses_validation() + { + var modelBuilder = Fixture.CreateModelBuilder(); + modelBuilder.Entity("Dummy"); + + Assert.Equal( + CoreStrings.ShadowEntity("Dummy"), + Assert.Throws + (() => modelBuilder.FinalizeModel()).Message); + } + [Fact] public virtual void Nullable_client_side_concurrency_token_can_be_used() { diff --git a/src/EFCore.Specification.Tests/TestUtilities/TestModelSource.cs b/src/EFCore.Specification.Tests/TestUtilities/TestModelSource.cs index 9bac9bdb038..4663efe4276 100644 --- a/src/EFCore.Specification.Tests/TestUtilities/TestModelSource.cs +++ b/src/EFCore.Specification.Tests/TestUtilities/TestModelSource.cs @@ -27,13 +27,12 @@ protected override IModel CreateModel(DbContext context, IConventionSetBuilder c var modelBuilder = new ModelBuilder(conventionSet); var model = modelBuilder.GetInfrastructure().Metadata; - model.SetProductVersion(ProductInfo.GetVersion()); Dependencies.ModelCustomizer.Customize(modelBuilder, context); _onModelCreating(modelBuilder, context); - model.Validate(); + modelBuilder.FinalizeModel(); validator.Validate(model); diff --git a/src/EFCore/Infrastructure/ModelSource.cs b/src/EFCore/Infrastructure/ModelSource.cs index 82dbc42db46..82dda96af83 100644 --- a/src/EFCore/Infrastructure/ModelSource.cs +++ b/src/EFCore/Infrastructure/ModelSource.cs @@ -79,11 +79,10 @@ protected virtual IModel CreateModel( var modelBuilder = new ModelBuilder(conventionSet); var model = modelBuilder.GetInfrastructure().Metadata; - model.SetProductVersion(ProductInfo.GetVersion()); Dependencies.ModelCustomizer.Customize(modelBuilder, context); - model.Validate(); + modelBuilder.FinalizeModel(); validator.Validate(model); diff --git a/src/EFCore/Metadata/Conventions/ConventionSet.cs b/src/EFCore/Metadata/Conventions/ConventionSet.cs index ed58894bbf4..a1288c2e1ed 100644 --- a/src/EFCore/Metadata/Conventions/ConventionSet.cs +++ b/src/EFCore/Metadata/Conventions/ConventionSet.cs @@ -162,7 +162,15 @@ public class ConventionSet /// directly from your code. This API may change or be removed in future releases. /// public static ConventionSet CreateConventionSet([NotNull] DbContext context) - => new CompositeConventionSetBuilder(context.GetService>().ToList()) - .AddConventions(context.GetService().CreateConventionSet()); + { + var conventionSet = new CompositeConventionSetBuilder( + context.GetService>().ToList()) + .AddConventions( + context.GetService().CreateConventionSet()); + + conventionSet.ModelBuiltConventions.Add(new ValidatingConvention(context.GetService())); + + return conventionSet; + } } } diff --git a/src/EFCore/Metadata/Conventions/Internal/ValidatingConvention.cs b/src/EFCore/Metadata/Conventions/Internal/ValidatingConvention.cs new file mode 100644 index 00000000000..a2f74bbbe18 --- /dev/null +++ b/src/EFCore/Metadata/Conventions/Internal/ValidatingConvention.cs @@ -0,0 +1,38 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using JetBrains.Annotations; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata.Internal; + +namespace Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal +{ + /// + /// This API supports the Entity Framework Core infrastructure and is not intended to be used + /// directly from your code. This API may change or be removed in future releases. + /// + public class ValidatingConvention : IModelBuiltConvention + { + private readonly IModelValidator _validator; + + /// + /// This API supports the Entity Framework Core infrastructure and is not intended to be used + /// directly from your code. This API may change or be removed in future releases. + /// + public ValidatingConvention([NotNull] IModelValidator validator) + { + _validator = validator; + } + + /// + /// This API supports the Entity Framework Core infrastructure and is not intended to be used + /// directly from your code. This API may change or be removed in future releases. + /// + public virtual InternalModelBuilder Apply(InternalModelBuilder modelBuilder) + { + _validator.Validate(modelBuilder.Metadata); + + return modelBuilder; + } + } +} diff --git a/src/EFCore/ModelBuilder.cs b/src/EFCore/ModelBuilder.cs index f7c80a3562f..df950d484be 100644 --- a/src/EFCore/ModelBuilder.cs +++ b/src/EFCore/ModelBuilder.cs @@ -5,6 +5,7 @@ using System.ComponentModel; using JetBrains.Annotations; using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Internal; using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Metadata.Builders; using Microsoft.EntityFrameworkCore.Metadata.Conventions; @@ -38,6 +39,8 @@ public ModelBuilder([NotNull] ConventionSet conventions) Check.NotNull(conventions, nameof(conventions)); _builder = new InternalModelBuilder(new Model(conventions)); + + _builder.Metadata.SetProductVersion(ProductInfo.GetVersion()); } /// @@ -393,6 +396,21 @@ public virtual ModelBuilder UsePropertyAccessMode(PropertyAccessMode propertyAcc return this; } + /// + /// Forces post-processing on the model such that it is ready for use by the runtime. This post + /// processing happens automatically when using OnModelCreating; this method allows it to be run + /// explicitly in cases where the automatic execution is not possible. + /// + /// + /// The same instance so that additional configuration calls can be chained. + /// + public virtual ModelBuilder FinalizeModel() + { + Builder.Metadata.Validate(); + + return this; + } + private InternalModelBuilder Builder => this.GetInfrastructure(); #region Hidden System.Object members diff --git a/test/EFCore.Design.Tests/Migrations/Design/CSharpMigrationsGeneratorTest.cs b/test/EFCore.Design.Tests/Migrations/Design/CSharpMigrationsGeneratorTest.cs index 690a8408351..d0e772aaa4e 100644 --- a/test/EFCore.Design.Tests/Migrations/Design/CSharpMigrationsGeneratorTest.cs +++ b/test/EFCore.Design.Tests/Migrations/Design/CSharpMigrationsGeneratorTest.cs @@ -273,6 +273,7 @@ public void Snapshot_with_enum_discriminator_uses_converted_values() codeHelper)))); var modelBuilder = RelationalTestHelpers.Instance.CreateConventionBuilder(); + modelBuilder.Model.RemoveAnnotation(CoreAnnotationNames.ProductVersionAnnotation); modelBuilder.Entity( eb => { @@ -282,7 +283,7 @@ public void Snapshot_with_enum_discriminator_uses_converted_values() eb.Property("EnumDiscriminator").HasConversion(); }); - modelBuilder.GetInfrastructure().Metadata.Validate(); + modelBuilder.FinalizeModel(); var modelSnapshotCode = generator.GenerateSnapshot( "MyNamespace", @@ -336,7 +337,7 @@ private static void AssertConverter(ValueConverter valueConverter, string expect var property = modelBuilder.Entity().Property(e => e.Id).Metadata; property.SetMaxLength(1000); - modelBuilder.GetInfrastructure().Metadata.Validate(); + modelBuilder.FinalizeModel(); var codeHelper = new CSharpHelper(new SqlServerTypeMappingSource( TestServiceFactory.Instance.Create(), @@ -520,6 +521,7 @@ public void Snapshots_compile() var generator = CreateMigrationsCodeGenerator(); var modelBuilder = RelationalTestHelpers.Instance.CreateConventionBuilder(); + modelBuilder.Model.RemoveAnnotation(CoreAnnotationNames.ProductVersionAnnotation); modelBuilder.Entity( x => { @@ -539,7 +541,7 @@ public void Snapshots_compile() var property2 = entityType.AddProperty("Ham", typeof(RawEnum)); property2.SetValueConverter(new ValueConverter(v => v.ToString(), v => (RawEnum)Enum.Parse(typeof(RawEnum), v), new ConverterMappingHints(size: 10))); - modelBuilder.GetInfrastructure().Metadata.Validate(); + modelBuilder.FinalizeModel(); var modelSnapshotCode = generator.GenerateSnapshot( "MyNamespace", diff --git a/test/EFCore.Design.Tests/Migrations/ModelSnapshotSqlServerTest.cs b/test/EFCore.Design.Tests/Migrations/ModelSnapshotSqlServerTest.cs index 04455e767ed..326dd8937be 100644 --- a/test/EFCore.Design.Tests/Migrations/ModelSnapshotSqlServerTest.cs +++ b/test/EFCore.Design.Tests/Migrations/ModelSnapshotSqlServerTest.cs @@ -3186,10 +3186,10 @@ protected void Test(Action buildModel, string expectedCode, Action { var modelBuilder = CreateConventionalModelBuilder(); modelBuilder.HasChangeTrackingStrategy(ChangeTrackingStrategy.Snapshot); + modelBuilder.Model.RemoveAnnotation(CoreAnnotationNames.ProductVersionAnnotation); buildModel(modelBuilder); - modelBuilder.GetInfrastructure().Metadata.Validate(); - CreateModelValidator().Validate(modelBuilder.Model); + modelBuilder.FinalizeModel(); var model = modelBuilder.Model; var codeHelper = new CSharpHelper( @@ -3238,6 +3238,7 @@ protected void Test(Action buildModel, string expectedCode, Action null); var builder = new ModelBuilder(new ConventionSet()); + builder.Model.RemoveAnnotation(CoreAnnotationNames.ProductVersionAnnotation); buildModelMethod.Invoke( Activator.CreateInstance(factoryType), @@ -3266,24 +3267,5 @@ protected ModelBuilder CreateConventionalModelBuilder() } } } - - protected ModelValidator CreateModelValidator() - => new SqlServerModelValidator( - new ModelValidatorDependencies( - new DiagnosticsLogger( - new ListLoggerFactory(l => false), - new LoggingOptions(), - new DiagnosticListener("Fake")), - new DiagnosticsLogger( - new ListLoggerFactory(l => false), - new LoggingOptions(), - new DiagnosticListener("Fake"))), - new RelationalModelValidatorDependencies( -#pragma warning disable 618 - TestServiceFactory.Instance.Create(), -#pragma warning restore 618 - new SqlServerTypeMappingSource( - TestServiceFactory.Instance.Create(), - TestServiceFactory.Instance.Create()))); } } diff --git a/test/EFCore.Design.Tests/Scaffolding/Internal/ModelCodeGeneratorTestBase.cs b/test/EFCore.Design.Tests/Scaffolding/Internal/ModelCodeGeneratorTestBase.cs index af36bc04d67..626e0058f47 100644 --- a/test/EFCore.Design.Tests/Scaffolding/Internal/ModelCodeGeneratorTestBase.cs +++ b/test/EFCore.Design.Tests/Scaffolding/Internal/ModelCodeGeneratorTestBase.cs @@ -8,23 +8,46 @@ using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Metadata.Conventions; +using Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal; +using Microsoft.EntityFrameworkCore.Metadata.Internal; using Microsoft.EntityFrameworkCore.SqlServer.Design.Internal; using Microsoft.EntityFrameworkCore.TestUtilities; using Microsoft.Extensions.DependencyInjection; namespace Microsoft.EntityFrameworkCore.Scaffolding.Internal { + public abstract class ModelCodeGeneratorTestBase { + public static ConventionSet BuildNonValidatingConventionSet() + { + var serviceProvider = new ServiceCollection() + .AddEntityFrameworkSqlServer() + .AddDbContext(o => o.UseSqlServer("Server=.")) + .BuildServiceProvider(); + + using (var serviceScope = serviceProvider.GetRequiredService().CreateScope()) + { + using (var context = serviceScope.ServiceProvider.GetService()) + { + return new CompositeConventionSetBuilder( + context.GetService>().ToList()) + .AddConventions( + context.GetService().CreateConventionSet()); + } + } + } + protected void Test( Action buildModel, ModelCodeGenerationOptions options, Action assertScaffold, Action assertModel) { - var modelBuilder = new ModelBuilder(SqlServerConventionSetBuilder.Build()); + var modelBuilder = new ModelBuilder(BuildNonValidatingConventionSet()); + modelBuilder.Model.RemoveAnnotation(CoreAnnotationNames.ProductVersionAnnotation); buildModel(modelBuilder); - modelBuilder.GetInfrastructure().Metadata.Validate(); + modelBuilder.FinalizeModel(); var model = modelBuilder.Model; diff --git a/test/EFCore.InMemory.FunctionalTests/F1InMemoryFixture.cs b/test/EFCore.InMemory.FunctionalTests/F1InMemoryFixture.cs index 4ef2d09b2a4..1f407431118 100644 --- a/test/EFCore.InMemory.FunctionalTests/F1InMemoryFixture.cs +++ b/test/EFCore.InMemory.FunctionalTests/F1InMemoryFixture.cs @@ -1,12 +1,16 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +using Microsoft.EntityFrameworkCore.InMemory.Metadata.Conventions.Internal; using Microsoft.EntityFrameworkCore.TestUtilities; namespace Microsoft.EntityFrameworkCore { public class F1InMemoryFixture : F1FixtureBase { + public override ModelBuilder CreateModelBuilder() + => new ModelBuilder(InMemoryConventionSetBuilder.Build()); + protected override ITestStoreFactory TestStoreFactory => InMemoryTestStoreFactory.Instance; } } diff --git a/test/EFCore.Relational.Tests/Migrations/Internal/MigrationsModelDifferTest.cs b/test/EFCore.Relational.Tests/Migrations/Internal/MigrationsModelDifferTest.cs index 7b4933f033a..7c8a75600dc 100644 --- a/test/EFCore.Relational.Tests/Migrations/Internal/MigrationsModelDifferTest.cs +++ b/test/EFCore.Relational.Tests/Migrations/Internal/MigrationsModelDifferTest.cs @@ -1595,8 +1595,7 @@ public void Rename_property_and_column_when_snapshot() var targetModelBuilder = CreateModelBuilder(); targetModelBuilder.Entity(); - // NB: Call Validate() so ModelBuilt conventions are applied. - targetModelBuilder.GetInfrastructure().Metadata.Validate(); + targetModelBuilder.FinalizeModel(); var modelDiffer = RelationalTestHelpers.Instance.CreateContextServices() .GetRequiredService(); diff --git a/test/EFCore.Relational.Tests/Migrations/Internal/MigrationsModelDifferTestBase.cs b/test/EFCore.Relational.Tests/Migrations/Internal/MigrationsModelDifferTestBase.cs index b9c6157f685..0d1608d19ed 100644 --- a/test/EFCore.Relational.Tests/Migrations/Internal/MigrationsModelDifferTestBase.cs +++ b/test/EFCore.Relational.Tests/Migrations/Internal/MigrationsModelDifferTestBase.cs @@ -41,12 +41,12 @@ protected void Execute( var sourceModelBuilder = CreateModelBuilder(); buildCommonAction(sourceModelBuilder); buildSourceAction(sourceModelBuilder); - sourceModelBuilder.GetInfrastructure().Metadata.Validate(); + sourceModelBuilder.FinalizeModel(); var targetModelBuilder = CreateModelBuilder(); buildCommonAction(targetModelBuilder); buildTargetAction(targetModelBuilder); - targetModelBuilder.GetInfrastructure().Metadata.Validate(); + targetModelBuilder.FinalizeModel(); var modelDiffer = CreateModelDiffer(targetModelBuilder.Model); diff --git a/test/EFCore.SqlServer.FunctionalTests/F1SqlServerFixture.cs b/test/EFCore.SqlServer.FunctionalTests/F1SqlServerFixture.cs index 357d811b400..652e6839611 100644 --- a/test/EFCore.SqlServer.FunctionalTests/F1SqlServerFixture.cs +++ b/test/EFCore.SqlServer.FunctionalTests/F1SqlServerFixture.cs @@ -1,7 +1,7 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -using Microsoft.EntityFrameworkCore.Diagnostics; +using Microsoft.EntityFrameworkCore.Metadata.Conventions; using Microsoft.EntityFrameworkCore.TestModels.ConcurrencyModel; using Microsoft.EntityFrameworkCore.TestUtilities; @@ -11,9 +11,12 @@ public class F1SqlServerFixture : F1RelationalFixture { protected override ITestStoreFactory TestStoreFactory => SqlServerTestStoreFactory.Instance; - protected override void OnModelCreating(ModelBuilder modelBuilder, DbContext context) + public override ModelBuilder CreateModelBuilder() + => new ModelBuilder(SqlServerConventionSetBuilder.Build()); + + protected override void BuildModelExternal(ModelBuilder modelBuilder) { - base.OnModelCreating(modelBuilder, context); + base.BuildModelExternal(modelBuilder); modelBuilder.Entity().Property("Version").IsRowVersion(); modelBuilder.Entity().Property("Version").IsRowVersion(); diff --git a/test/EFCore.SqlServer.Tests/Metadata/Conventions/SqlServerValueGenerationStrategyConventionTest.cs b/test/EFCore.SqlServer.Tests/Metadata/Conventions/SqlServerValueGenerationStrategyConventionTest.cs index ac972155120..62264fc93f8 100644 --- a/test/EFCore.SqlServer.Tests/Metadata/Conventions/SqlServerValueGenerationStrategyConventionTest.cs +++ b/test/EFCore.SqlServer.Tests/Metadata/Conventions/SqlServerValueGenerationStrategyConventionTest.cs @@ -2,6 +2,7 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System.Linq; +using Microsoft.EntityFrameworkCore.Metadata.Internal; using Microsoft.EntityFrameworkCore.SqlServer.Metadata.Internal; using Microsoft.EntityFrameworkCore.TestUtilities; using Xunit; @@ -15,6 +16,7 @@ public class SqlServerValueGenerationStrategyConventionTest public void Annotations_are_added_when_conventional_model_builder_is_used() { var model = SqlServerTestHelpers.Instance.CreateConventionBuilder().Model; + model.RemoveAnnotation(CoreAnnotationNames.ProductVersionAnnotation); var annotations = model.GetAnnotations().OrderBy(a => a.Name).ToList(); Assert.Equal(2, annotations.Count); @@ -30,6 +32,8 @@ public void Annotations_are_added_when_conventional_model_builder_is_used_with_s .ForSqlServerUseSequenceHiLo() .Model; + model.RemoveAnnotation(CoreAnnotationNames.ProductVersionAnnotation); + var annotations = model.GetAnnotations().OrderBy(a => a.Name).ToList(); Assert.Equal(4, annotations.Count); diff --git a/test/EFCore.Sqlite.FunctionalTests/F1SqliteFixture.cs b/test/EFCore.Sqlite.FunctionalTests/F1SqliteFixture.cs index d089eace65d..8becffc251d 100644 --- a/test/EFCore.Sqlite.FunctionalTests/F1SqliteFixture.cs +++ b/test/EFCore.Sqlite.FunctionalTests/F1SqliteFixture.cs @@ -1,6 +1,7 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +using Microsoft.EntityFrameworkCore.Metadata.Conventions; using Microsoft.EntityFrameworkCore.TestUtilities; namespace Microsoft.EntityFrameworkCore @@ -8,5 +9,8 @@ namespace Microsoft.EntityFrameworkCore public class F1SqliteFixture : F1RelationalFixture { protected override ITestStoreFactory TestStoreFactory => PrivateCacheSqliteTestStoreFactory.Instance; + + public override ModelBuilder CreateModelBuilder() + => new ModelBuilder(SqliteConventionSetBuilder.Build()); } }