diff --git a/eng/Versions.props b/eng/Versions.props
index 1f893e018ea..a409b9ab0f2 100644
--- a/eng/Versions.props
+++ b/eng/Versions.props
@@ -37,5 +37,6 @@
4.5.0
1.1.2-beta1.23371.1
+ 2.6.1
diff --git a/src/EFCore/Metadata/Internal/Model.cs b/src/EFCore/Metadata/Internal/Model.cs
index dfc86b1bad6..646d0f5e3da 100644
--- a/src/EFCore/Metadata/Internal/Model.cs
+++ b/src/EFCore/Metadata/Internal/Model.cs
@@ -51,9 +51,10 @@ public class Model : ConventionAnnotatable, IMutableModel, IConventionModel, IRu
/// any release. You should only use it directly in your code with extreme caution and knowing that
/// doing so can result in application failures when updating to a new Entity Framework Core release.
///
- public Model()
+ public Model(Guid? modelId = null)
: this(new ConventionSet())
{
+ ModelId = modelId ?? Guid.NewGuid();
}
///
@@ -75,6 +76,7 @@ public Model(ConventionSet conventions, ModelDependencies? modelDependencies = n
_modelFinalizedConventions = conventions.ModelFinalizedConventions;
Builder = builder;
Configuration = modelConfiguration;
+ ModelId = Guid.NewGuid();
dispatcher.OnModelInitialized(builder);
}
@@ -459,7 +461,7 @@ public virtual IEnumerable FindEntityTypes(Type type)
/// any release. You should only use it directly in your code with extreme caution and knowing that
/// doing so can result in application failures when updating to a new Entity Framework Core release.
///
- public virtual Guid ModelId { get; set; } = Guid.NewGuid();
+ public virtual Guid ModelId { get; set; }
///
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
diff --git a/test/EFCore.Cosmos.Tests/ModelBuilding/CosmosModelBuilderGenericTest.cs b/test/EFCore.Cosmos.Tests/ModelBuilding/CosmosModelBuilderGenericTest.cs
index 48c428d3bd8..0dd3ed80234 100644
--- a/test/EFCore.Cosmos.Tests/ModelBuilding/CosmosModelBuilderGenericTest.cs
+++ b/test/EFCore.Cosmos.Tests/ModelBuilding/CosmosModelBuilderGenericTest.cs
@@ -9,8 +9,13 @@ namespace Microsoft.EntityFrameworkCore.ModelBuilding;
public class CosmosModelBuilderGenericTest : ModelBuilderGenericTest
{
- public class CosmosGenericNonRelationship : GenericNonRelationship
+ public class CosmosGenericNonRelationship : GenericNonRelationship, IClassFixture
{
+ public CosmosGenericNonRelationship(CosmosModelBuilderFixture fixture)
+ : base(fixture)
+ {
+ }
+
public override void Can_set_composite_key_for_primitive_collection_on_an_entity_with_fields()
=> Assert.Equal(
CosmosStrings.PrimitiveCollectionsNotSupported(nameof(EntityWithFields), "CollectionCompanyId"),
@@ -433,8 +438,13 @@ protected override TestModelBuilder CreateModelBuilder(Action CreateTestModelBuilder(CosmosTestHelpers.Instance, configure);
}
- public class CosmosGenericComplexType : GenericComplexType
+ public class CosmosGenericComplexType : GenericComplexType, IClassFixture
{
+ public CosmosGenericComplexType(CosmosModelBuilderFixture fixture)
+ : base(fixture)
+ {
+ }
+
public override void Access_mode_can_be_overridden_at_entity_and_property_levels()
=> Assert.Equal(
CosmosStrings.PrimitiveCollectionsNotSupported(nameof(CollectionQuarks), "Down"),
@@ -766,8 +776,13 @@ protected override TestModelBuilder CreateModelBuilder(Action CreateTestModelBuilder(CosmosTestHelpers.Instance, configure);
}
- public class CosmosGenericInheritance : GenericInheritance
+ public class CosmosGenericInheritance : GenericInheritance, IClassFixture
{
+ public CosmosGenericInheritance(CosmosModelBuilderFixture fixture)
+ : base(fixture)
+ {
+ }
+
public override void Base_type_can_be_discovered_after_creating_foreign_keys_on_derived()
{
var mb = CreateModelBuilder();
@@ -795,8 +810,13 @@ protected override TestModelBuilder CreateModelBuilder(Action CreateTestModelBuilder(CosmosTestHelpers.Instance, configure);
}
- public class CosmosGenericOneToMany : GenericOneToMany
+ public class CosmosGenericOneToMany : GenericOneToMany, IClassFixture
{
+ public CosmosGenericOneToMany(CosmosModelBuilderFixture fixture)
+ : base(fixture)
+ {
+ }
+
public override void Navigation_to_shared_type_is_not_discovered_by_convention()
{
var modelBuilder = CreateModelBuilder();
@@ -818,14 +838,24 @@ protected override TestModelBuilder CreateModelBuilder(Action CreateTestModelBuilder(CosmosTestHelpers.Instance, configure);
}
- public class CosmosGenericManyToOne : GenericManyToOne
+ public class CosmosGenericManyToOne : GenericManyToOne, IClassFixture
{
+ public CosmosGenericManyToOne(CosmosModelBuilderFixture fixture)
+ : base(fixture)
+ {
+ }
+
protected override TestModelBuilder CreateModelBuilder(Action configure = null)
=> CreateTestModelBuilder(CosmosTestHelpers.Instance, configure);
}
- public class CosmosGenericOneToOne : GenericOneToOne
+ public class CosmosGenericOneToOne : GenericOneToOne, IClassFixture
{
+ public CosmosGenericOneToOne(CosmosModelBuilderFixture fixture)
+ : base(fixture)
+ {
+ }
+
public override void Navigation_to_shared_type_is_not_discovered_by_convention()
{
var modelBuilder = CreateModelBuilder();
@@ -847,8 +877,13 @@ protected override TestModelBuilder CreateModelBuilder(Action CreateTestModelBuilder(CosmosTestHelpers.Instance, configure);
}
- public class CosmosGenericManyToMany : GenericManyToMany
+ public class CosmosGenericManyToMany : GenericManyToMany, IClassFixture
{
+ public CosmosGenericManyToMany(CosmosModelBuilderFixture fixture)
+ : base(fixture)
+ {
+ }
+
[ConditionalFact]
public virtual void Can_use_shared_type_as_join_entity_with_partition_keys()
{
@@ -1002,8 +1037,13 @@ protected override TestModelBuilder CreateModelBuilder(Action CreateTestModelBuilder(CosmosTestHelpers.Instance, configure);
}
- public class CosmosGenericOwnedTypes : GenericOwnedTypes
+ public class CosmosGenericOwnedTypes : GenericOwnedTypes, IClassFixture
{
+ public CosmosGenericOwnedTypes(CosmosModelBuilderFixture fixture)
+ : base(fixture)
+ {
+ }
+
public override void Deriving_from_owned_type_throws()
// On Cosmos the base type starts as owned
=> Assert.Contains(
@@ -1048,4 +1088,19 @@ public virtual void Reference_type_is_discovered_as_owned()
protected override TestModelBuilder CreateModelBuilder(Action configure = null)
=> CreateTestModelBuilder(CosmosTestHelpers.Instance, configure);
}
+
+ public class CosmosModelBuilderFixture : ModelBuilderFixtureBase
+ {
+ public override void AssertEqual(
+ IEnumerable expectedProperties,
+ IEnumerable actualProperties,
+ bool assertOrder = false,
+ bool compareAnnotations = false)
+ {
+ expectedProperties = expectedProperties.Where(p => p.Name != "__jObject" && p.Name != "__id");
+ actualProperties = actualProperties.Where(p => p.Name != "__jObject" && p.Name != "__id");
+
+ base.AssertEqual(expectedProperties, actualProperties, assertOrder, compareAnnotations);
+ }
+ }
}
diff --git a/test/EFCore.InMemory.Tests/ModelBuilding/InMemoryModelBuilderGenericTest.cs b/test/EFCore.InMemory.Tests/ModelBuilding/InMemoryModelBuilderGenericTest.cs
index 291cb87beb0..44a02ef57c5 100644
--- a/test/EFCore.InMemory.Tests/ModelBuilding/InMemoryModelBuilderGenericTest.cs
+++ b/test/EFCore.InMemory.Tests/ModelBuilding/InMemoryModelBuilderGenericTest.cs
@@ -9,26 +9,46 @@ namespace Microsoft.EntityFrameworkCore.ModelBuilding;
public class InMemoryModelBuilderGenericTest : ModelBuilderGenericTest
{
- public class InMemoryGenericNonRelationship : GenericNonRelationship
+ public class InMemoryGenericNonRelationship : GenericNonRelationship, IClassFixture
{
+ public InMemoryGenericNonRelationship(InMemoryModelBuilderFixture fixture)
+ : base(fixture)
+ {
+ }
+
protected override TestModelBuilder CreateModelBuilder(Action configure = null)
=> CreateTestModelBuilder(InMemoryTestHelpers.Instance, configure);
}
- public class InMemoryGenericComplexTypeTestBase : GenericComplexType
+ public class InMemoryGenericComplexTypeTestBase : GenericComplexType, IClassFixture
{
+ public InMemoryGenericComplexTypeTestBase(InMemoryModelBuilderFixture fixture)
+ : base(fixture)
+ {
+ }
+
protected override TestModelBuilder CreateModelBuilder(Action configure = null)
=> CreateTestModelBuilder(InMemoryTestHelpers.Instance, configure);
}
- public class InMemoryGenericInheritance : GenericInheritance
+ public class InMemoryGenericInheritance : GenericInheritance, IClassFixture
{
+ public InMemoryGenericInheritance(InMemoryModelBuilderFixture fixture)
+ : base(fixture)
+ {
+ }
+
protected override TestModelBuilder CreateModelBuilder(Action configure = null)
=> CreateTestModelBuilder(InMemoryTestHelpers.Instance, configure);
}
- public class InMemoryGenericOneToMany : GenericOneToMany
+ public class InMemoryGenericOneToMany : GenericOneToMany, IClassFixture
{
+ public InMemoryGenericOneToMany(InMemoryModelBuilderFixture fixture)
+ : base(fixture)
+ {
+ }
+
[ConditionalFact] // Issue #3376
public virtual void Can_use_self_referencing_overlapping_FK_PK()
{
@@ -145,14 +165,24 @@ protected override TestModelBuilder CreateModelBuilder(Action CreateTestModelBuilder(InMemoryTestHelpers.Instance, configure);
}
- public class InMemoryGenericManyToOne : GenericManyToOne
+ public class InMemoryGenericManyToOne : GenericManyToOne, IClassFixture
{
+ public InMemoryGenericManyToOne(InMemoryModelBuilderFixture fixture)
+ : base(fixture)
+ {
+ }
+
protected override TestModelBuilder CreateModelBuilder(Action configure = null)
=> CreateTestModelBuilder(InMemoryTestHelpers.Instance, configure);
}
- public class InMemoryGenericOneToOne : GenericOneToOne
+ public class InMemoryGenericOneToOne : GenericOneToOne, IClassFixture
{
+ public InMemoryGenericOneToOne(InMemoryModelBuilderFixture fixture)
+ : base(fixture)
+ {
+ }
+
[ConditionalFact]
public virtual void Can_use_self_referencing_overlapping_FK_PK()
{
@@ -236,9 +266,18 @@ protected override TestModelBuilder CreateModelBuilder(Action CreateTestModelBuilder(InMemoryTestHelpers.Instance, configure);
}
- public class InMemoryGenericOwnedTypes : GenericOwnedTypes
+ public class InMemoryGenericOwnedTypes : GenericOwnedTypes, IClassFixture
{
+ public InMemoryGenericOwnedTypes(InMemoryModelBuilderFixture fixture)
+ : base(fixture)
+ {
+ }
+
protected override TestModelBuilder CreateModelBuilder(Action configure = null)
=> CreateTestModelBuilder(InMemoryTestHelpers.Instance, configure);
}
+
+ public class InMemoryModelBuilderFixture : ModelBuilderFixtureBase
+ {
+ }
}
diff --git a/test/EFCore.Relational.Tests/Metadata/RelationalModelTest.cs b/test/EFCore.Relational.Tests/Metadata/RelationalModelTest.cs
index cfb5a489bcc..c5b569922bf 100644
--- a/test/EFCore.Relational.Tests/Metadata/RelationalModelTest.cs
+++ b/test/EFCore.Relational.Tests/Metadata/RelationalModelTest.cs
@@ -3164,8 +3164,8 @@ public static void AssertEqual(IRelationalModel expectedModel, IRelationalModel
expectedModel.StoredProcedures.ZipAssert(actualModel.StoredProcedures, AssertEqual);
Assert.Equal(((RelationalModel)expectedModel).IsReadOnly, ((RelationalModel)actualModel).IsReadOnly);
- Assert.Equal(expectedModel.GetAnnotations(), actualModel.GetAnnotations(), AnnotationComparer.Instance);
- Assert.Equal(expectedModel.GetRuntimeAnnotations(), actualModel.GetRuntimeAnnotations(), AnnotationComparer.Instance);
+ Assert.Equal(expectedModel.GetAnnotations(), actualModel.GetAnnotations(), TestAnnotationComparer.Instance);
+ Assert.Equal(expectedModel.GetRuntimeAnnotations(), actualModel.GetRuntimeAnnotations(), TestAnnotationComparer.Instance);
}
public static void AssertEqualBase(ITableBase expected, ITableBase actual)
@@ -3191,8 +3191,8 @@ public static void AssertEqualBase(ITableBase expected, ITableBase actual)
var actualEntityType = actual.ComplexTypeMappings.Single(m => m.TypeBase.Name == expectedEntityType.Name).TypeBase;
}
- Assert.Equal(expected.GetAnnotations(), actual.GetAnnotations(), AnnotationComparer.Instance);
- Assert.Equal(expected.GetRuntimeAnnotations(), actual.GetRuntimeAnnotations(), AnnotationComparer.Instance);
+ Assert.Equal(expected.GetAnnotations(), actual.GetAnnotations(), TestAnnotationComparer.Instance);
+ Assert.Equal(expected.GetRuntimeAnnotations(), actual.GetRuntimeAnnotations(), TestAnnotationComparer.Instance);
}
public static void AssertEqual(ITableBase expected, ITableBase actual)
@@ -3213,8 +3213,8 @@ public static void AssertEqualBase(ITableMappingBase expected, ITableMappingBase
Assert.Equal(expected.IsSharedTablePrincipal, actual.IsSharedTablePrincipal);
Assert.Equal(expected.IsSplitEntityTypePrincipal, actual.IsSplitEntityTypePrincipal);
- Assert.Equal(expected.GetAnnotations(), actual.GetAnnotations(), AnnotationComparer.Instance);
- Assert.Equal(expected.GetRuntimeAnnotations(), actual.GetRuntimeAnnotations(), AnnotationComparer.Instance);
+ Assert.Equal(expected.GetAnnotations(), actual.GetAnnotations(), TestAnnotationComparer.Instance);
+ Assert.Equal(expected.GetRuntimeAnnotations(), actual.GetRuntimeAnnotations(), TestAnnotationComparer.Instance);
}
public static void AssertEqual(ITableMappingBase expected, ITableMappingBase actual)
@@ -3232,8 +3232,8 @@ public static void AssertEqualBase(IColumnBase expected, IColumnBase actual)
Assert.Equal(expected.StoreType, actual.StoreType);
Assert.Equal(expected.StoreTypeMapping.StoreType, actual.StoreTypeMapping.StoreType);
- Assert.Equal(expected.GetAnnotations(), actual.GetAnnotations(), AnnotationComparer.Instance);
- Assert.Equal(expected.GetRuntimeAnnotations(), actual.GetRuntimeAnnotations(), AnnotationComparer.Instance);
+ Assert.Equal(expected.GetAnnotations(), actual.GetAnnotations(), TestAnnotationComparer.Instance);
+ Assert.Equal(expected.GetRuntimeAnnotations(), actual.GetRuntimeAnnotations(), TestAnnotationComparer.Instance);
}
public static void AssertEqual(IColumnBase expected, IColumnBase actual)
@@ -3251,8 +3251,8 @@ public static void AssertEqualBase(IColumnMappingBase expected, IColumnMappingBa
Assert.Equal(expected.Property.Name, actual.Property.Name);
Assert.Equal(expected.TypeMapping.StoreType, actual.TypeMapping.StoreType);
- Assert.Equal(expected.GetAnnotations(), actual.GetAnnotations(), AnnotationComparer.Instance);
- Assert.Equal(expected.GetRuntimeAnnotations(), actual.GetRuntimeAnnotations(), AnnotationComparer.Instance);
+ Assert.Equal(expected.GetAnnotations(), actual.GetAnnotations(), TestAnnotationComparer.Instance);
+ Assert.Equal(expected.GetRuntimeAnnotations(), actual.GetRuntimeAnnotations(), TestAnnotationComparer.Instance);
}
public static void AssertEqual(IColumnMappingBase expected, IColumnMappingBase actual)
@@ -3313,8 +3313,8 @@ public static void AssertEqual(ITableIndex expected, ITableIndex actual)
actual.MappedIndexes.Select(i => i.Properties.Select(p => p.Name)),
expected.MappedIndexes.Select(i => i.Properties.Select(p => p.Name)));
- Assert.Equal(expected.GetAnnotations(), actual.GetAnnotations(), AnnotationComparer.Instance);
- Assert.Equal(expected.GetRuntimeAnnotations(), actual.GetRuntimeAnnotations(), AnnotationComparer.Instance);
+ Assert.Equal(expected.GetAnnotations(), actual.GetAnnotations(), TestAnnotationComparer.Instance);
+ Assert.Equal(expected.GetRuntimeAnnotations(), actual.GetRuntimeAnnotations(), TestAnnotationComparer.Instance);
}
public static void AssertEqual(IForeignKeyConstraint expected, IForeignKeyConstraint actual)
@@ -3330,8 +3330,8 @@ public static void AssertEqual(IForeignKeyConstraint expected, IForeignKeyConstr
actual.MappedForeignKeys.Select(i => i.Properties.Select(p => p.Name)),
expected.MappedForeignKeys.Select(i => i.Properties.Select(p => p.Name)));
- Assert.Equal(expected.GetAnnotations(), actual.GetAnnotations(), AnnotationComparer.Instance);
- Assert.Equal(expected.GetRuntimeAnnotations(), actual.GetRuntimeAnnotations(), AnnotationComparer.Instance);
+ Assert.Equal(expected.GetAnnotations(), actual.GetAnnotations(), TestAnnotationComparer.Instance);
+ Assert.Equal(expected.GetRuntimeAnnotations(), actual.GetRuntimeAnnotations(), TestAnnotationComparer.Instance);
}
public static void AssertEqual(IUniqueConstraint expected, IUniqueConstraint actual)
@@ -3344,8 +3344,8 @@ public static void AssertEqual(IUniqueConstraint expected, IUniqueConstraint act
actual.MappedKeys.Select(i => i.Properties.Select(p => p.Name)),
expected.MappedKeys.Select(i => i.Properties.Select(p => p.Name)));
- Assert.Equal(expected.GetAnnotations(), actual.GetAnnotations(), AnnotationComparer.Instance);
- Assert.Equal(expected.GetRuntimeAnnotations(), actual.GetRuntimeAnnotations(), AnnotationComparer.Instance);
+ Assert.Equal(expected.GetAnnotations(), actual.GetAnnotations(), TestAnnotationComparer.Instance);
+ Assert.Equal(expected.GetRuntimeAnnotations(), actual.GetRuntimeAnnotations(), TestAnnotationComparer.Instance);
}
public static void AssertEqual(ITrigger expected, ITrigger actual)
@@ -3354,8 +3354,8 @@ public static void AssertEqual(ITrigger expected, ITrigger actual)
Assert.Equal(expected.GetTableName(), actual.GetTableName());
Assert.Equal(expected.GetTableSchema(), actual.GetTableSchema());
- Assert.Equal(expected.GetAnnotations(), actual.GetAnnotations(), AnnotationComparer.Instance);
- Assert.Equal(expected.GetRuntimeAnnotations(), actual.GetRuntimeAnnotations(), AnnotationComparer.Instance);
+ Assert.Equal(expected.GetAnnotations(), actual.GetAnnotations(), TestAnnotationComparer.Instance);
+ Assert.Equal(expected.GetRuntimeAnnotations(), actual.GetRuntimeAnnotations(), TestAnnotationComparer.Instance);
}
public static void AssertEqual(IView expected, IView actual)
@@ -3453,8 +3453,8 @@ public static void AssertEqual(IFunctionMapping expected, IFunctionMapping actua
Assert.Equal(expected.IsDefaultFunctionMapping, actual.IsDefaultFunctionMapping);
Assert.Contains(expected.DbFunction.Name, actual.DbFunction.Name);
- Assert.Equal(expected.GetAnnotations(), actual.GetAnnotations(), AnnotationComparer.Instance);
- Assert.Equal(expected.GetRuntimeAnnotations(), actual.GetRuntimeAnnotations(), AnnotationComparer.Instance);
+ Assert.Equal(expected.GetAnnotations(), actual.GetAnnotations(), TestAnnotationComparer.Instance);
+ Assert.Equal(expected.GetRuntimeAnnotations(), actual.GetRuntimeAnnotations(), TestAnnotationComparer.Instance);
}
public static void AssertEqual(IFunctionColumn expected, IFunctionColumn actual)
@@ -3480,8 +3480,8 @@ public static void AssertEqual(IStoreFunctionParameter expected, IStoreFunctionP
Assert.Contains(actual, actual.Function.Parameters);
Assert.Equal(expected.DbFunctionParameters.Select(p => p.Name), actual.DbFunctionParameters.Select(p => p.Name));
- Assert.Equal(expected.GetAnnotations(), actual.GetAnnotations(), AnnotationComparer.Instance);
- Assert.Equal(expected.GetRuntimeAnnotations(), actual.GetRuntimeAnnotations(), AnnotationComparer.Instance);
+ Assert.Equal(expected.GetAnnotations(), actual.GetAnnotations(), TestAnnotationComparer.Instance);
+ Assert.Equal(expected.GetRuntimeAnnotations(), actual.GetRuntimeAnnotations(), TestAnnotationComparer.Instance);
}
public static void AssertEqual(IStoreStoredProcedure expected, IStoreStoredProcedure actual)
@@ -3524,8 +3524,8 @@ public static void AssertEqual(IStoredProcedureMapping expected, IStoredProcedur
Assert.Contains(expected.TableMapping?.Table.SchemaQualifiedName, actual.TableMapping?.Table.SchemaQualifiedName);
- Assert.Equal(expected.GetAnnotations(), actual.GetAnnotations(), AnnotationComparer.Instance);
- Assert.Equal(expected.GetRuntimeAnnotations(), actual.GetRuntimeAnnotations(), AnnotationComparer.Instance);
+ Assert.Equal(expected.GetAnnotations(), actual.GetAnnotations(), TestAnnotationComparer.Instance);
+ Assert.Equal(expected.GetRuntimeAnnotations(), actual.GetRuntimeAnnotations(), TestAnnotationComparer.Instance);
}
public static void AssertEqual(IStoreStoredProcedureResultColumn expected, IStoreStoredProcedureResultColumn actual)
diff --git a/test/EFCore.Relational.Tests/ModelBuilding/RelationalModelBuilderTest.cs b/test/EFCore.Relational.Tests/ModelBuilding/RelationalModelBuilderTest.cs
index d0fb6786d21..919dfb2992a 100644
--- a/test/EFCore.Relational.Tests/ModelBuilding/RelationalModelBuilderTest.cs
+++ b/test/EFCore.Relational.Tests/ModelBuilding/RelationalModelBuilderTest.cs
@@ -12,6 +12,11 @@ public class RelationalModelBuilderTest : ModelBuilderTest
{
public abstract class RelationalNonRelationshipTestBase : NonRelationshipTestBase
{
+ public RelationalNonRelationshipTestBase(RelationalModelBuilderFixture fixture)
+ : base(fixture)
+ {
+ }
+
[ConditionalFact]
public virtual void Can_use_table_splitting()
{
@@ -341,6 +346,11 @@ public virtual void Configuring_direction_on_RowsAffectedParameter_throws()
public abstract class RelationalComplexTypeTestBase : ComplexTypeTestBase
{
+ public RelationalComplexTypeTestBase(RelationalModelBuilderFixture fixture)
+ : base(fixture)
+ {
+ }
+
[ConditionalFact]
public virtual void Can_use_TPH()
{
@@ -649,6 +659,11 @@ public virtual void Configuring_direction_on_RowsAffectedParameter_throws()
public abstract class RelationalInheritanceTestBase : InheritanceTestBase
{
+ public RelationalInheritanceTestBase(RelationalModelBuilderFixture fixture)
+ : base(fixture)
+ {
+ }
+
[ConditionalFact]
public virtual void Can_use_table_splitting()
{
@@ -693,22 +708,43 @@ public virtual void Can_use_table_splitting()
public abstract class RelationalOneToManyTestBase : OneToManyTestBase
{
+ public RelationalOneToManyTestBase(RelationalModelBuilderFixture fixture)
+ : base(fixture)
+ {
+ }
}
public abstract class RelationalManyToOneTestBase : ManyToOneTestBase
{
+ public RelationalManyToOneTestBase(RelationalModelBuilderFixture fixture)
+ : base(fixture)
+ {
+ }
}
public abstract class RelationalOneToOneTestBase : OneToOneTestBase
{
+ public RelationalOneToOneTestBase(RelationalModelBuilderFixture fixture)
+ : base(fixture)
+ {
+ }
}
public abstract class RelationalManyToManyTestBase : ManyToManyTestBase
{
+ public RelationalManyToManyTestBase(RelationalModelBuilderFixture fixture)
+ : base(fixture)
+ {
+ }
}
public abstract class RelationalOwnedTypesTestBase : OwnedTypesTestBase
{
+ public RelationalOwnedTypesTestBase(RelationalModelBuilderFixture fixture)
+ : base(fixture)
+ {
+ }
+
[ConditionalFact]
public virtual void Can_use_table_splitting_with_owned_reference()
{
@@ -947,6 +983,7 @@ public virtual void Can_use_sproc_mapping_with_owned_reference()
Assert.Null(bookOwnership2.DeclaringEntityType.GetDeleteStoredProcedure());
}
#nullable disable
+
protected class JsonEntity
{
public int Id { get; set; }
@@ -1012,6 +1049,10 @@ protected class JsonEntityWithNesting
#nullable enable
}
+ public class RelationalModelBuilderFixture : ModelBuilderFixtureBase
+ {
+ }
+
public abstract class TestTableBuilder
where TEntity : class
{
diff --git a/test/EFCore.Specification.Tests/TestUtilities/ForeignKeyStrictComparer.cs b/test/EFCore.Specification.Tests/TestUtilities/ForeignKeyStrictComparer.cs
deleted file mode 100644
index 3329835b1ca..00000000000
--- a/test/EFCore.Specification.Tests/TestUtilities/ForeignKeyStrictComparer.cs
+++ /dev/null
@@ -1,40 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-namespace Microsoft.EntityFrameworkCore.TestUtilities;
-
-public class ForeignKeyStrictComparer : IEqualityComparer, IComparer
-{
- private readonly bool _compareAnnotations;
- private readonly bool _compareNavigations;
-
- public ForeignKeyStrictComparer(bool compareAnnotations = true, bool compareNavigations = true)
- {
- _compareAnnotations = compareAnnotations;
- _compareNavigations = compareNavigations;
- }
-
- public int Compare(IReadOnlyForeignKey x, IReadOnlyForeignKey y)
- => ForeignKeyComparer.Instance.Compare(x, y);
-
- public bool Equals(IReadOnlyForeignKey x, IReadOnlyForeignKey y)
- {
- if (x == null)
- {
- return y == null;
- }
-
- return y == null
- ? false
- : ForeignKeyComparer.Instance.Equals(x, y)
- && (x.IsUnique == y.IsUnique)
- && (x.IsRequired == y.IsRequired)
- && (!_compareNavigations
- || (new NavigationComparer(_compareAnnotations).Equals(x.DependentToPrincipal, y.DependentToPrincipal)
- && new NavigationComparer(_compareAnnotations).Equals(x.PrincipalToDependent, y.PrincipalToDependent)))
- && (!_compareAnnotations || x.GetAnnotations().SequenceEqual(y.GetAnnotations(), AnnotationComparer.Instance));
- }
-
- public int GetHashCode(IReadOnlyForeignKey obj)
- => ForeignKeyComparer.Instance.GetHashCode(obj);
-}
diff --git a/test/EFCore.Specification.Tests/TestUtilities/MetadataExtensions.cs b/test/EFCore.Specification.Tests/TestUtilities/MetadataExtensions.cs
index a3ceeb18820..b9b0bb96db8 100644
--- a/test/EFCore.Specification.Tests/TestUtilities/MetadataExtensions.cs
+++ b/test/EFCore.Specification.Tests/TestUtilities/MetadataExtensions.cs
@@ -23,133 +23,4 @@ public static void ForEach(this IEnumerable @this, Action action)
action(item);
}
}
-
- public static IReadOnlyModel Clone(this IReadOnlyModel model)
- {
- IMutableModel modelClone = new Model();
- var clonedEntityTypes = new Dictionary();
- foreach (var entityType in model.GetEntityTypes())
- {
- var clrType = entityType.ClrType;
- var clonedEntityType = clrType == null
- ? modelClone.AddEntityType(entityType.Name)
- : modelClone.AddEntityType(clrType);
-
- clonedEntityTypes.Add(entityType, clonedEntityType);
- }
-
- foreach (var clonedEntityType in clonedEntityTypes)
- {
- if (clonedEntityType.Key.BaseType != null)
- {
- clonedEntityType.Value.BaseType = clonedEntityTypes[clonedEntityType.Key.BaseType];
- }
- }
-
- foreach (var clonedEntityType in clonedEntityTypes)
- {
- CloneProperties(clonedEntityType.Key, clonedEntityType.Value);
- }
-
- foreach (var clonedEntityType in clonedEntityTypes)
- {
- CloneIndexes(clonedEntityType.Key, clonedEntityType.Value);
- }
-
- foreach (var clonedEntityType in clonedEntityTypes)
- {
- CloneKeys(clonedEntityType.Key, clonedEntityType.Value);
- }
-
- foreach (var clonedEntityType in clonedEntityTypes)
- {
- CloneForeignKeys(clonedEntityType.Key, clonedEntityType.Value);
- }
-
- foreach (var clonedEntityType in clonedEntityTypes)
- {
- CloneNavigations(clonedEntityType.Key, clonedEntityType.Value);
- }
-
- return modelClone;
- }
-
- private static void CloneProperties(IReadOnlyEntityType sourceEntityType, IMutableEntityType targetEntityType)
- {
- foreach (var property in sourceEntityType.GetDeclaredProperties())
- {
- var clonedProperty = targetEntityType.AddProperty(property.Name, property.ClrType);
- clonedProperty.IsNullable = property.IsNullable;
- clonedProperty.IsConcurrencyToken = property.IsConcurrencyToken;
- clonedProperty.ValueGenerated = property.ValueGenerated;
- clonedProperty.SetBeforeSaveBehavior(property.GetBeforeSaveBehavior());
- clonedProperty.SetAfterSaveBehavior(property.GetAfterSaveBehavior());
- property.GetAnnotations().ForEach(annotation => clonedProperty[annotation.Name] = annotation.Value);
- }
- }
-
- private static void CloneKeys(IReadOnlyEntityType sourceEntityType, IMutableEntityType targetEntityType)
- {
- foreach (var key in sourceEntityType.GetDeclaredKeys())
- {
- var clonedKey = targetEntityType.AddKey(
- key.Properties.Select(p => targetEntityType.FindProperty(p.Name)).ToList());
- if (key.IsPrimaryKey())
- {
- targetEntityType.SetPrimaryKey(clonedKey.Properties);
- }
-
- key.GetAnnotations().ForEach(annotation => clonedKey[annotation.Name] = annotation.Value);
- }
- }
-
- private static void CloneIndexes(IReadOnlyEntityType sourceEntityType, IMutableEntityType targetEntityType)
- {
- foreach (var index in sourceEntityType.GetDeclaredIndexes())
- {
- var clonedIndex = targetEntityType.AddIndex(
- index.Properties.Select(p => targetEntityType.FindProperty(p.Name)).ToList());
- clonedIndex.IsUnique = index.IsUnique;
- index.GetAnnotations().ForEach(annotation => clonedIndex[annotation.Name] = annotation.Value);
- }
- }
-
- private static void CloneForeignKeys(IReadOnlyEntityType sourceEntityType, IMutableEntityType targetEntityType)
- {
- foreach (var foreignKey in sourceEntityType.GetDeclaredForeignKeys())
- {
- var targetPrincipalEntityType = targetEntityType.Model.FindEntityType(foreignKey.PrincipalEntityType.Name);
- var clonedForeignKey = targetEntityType.AddForeignKey(
- foreignKey.Properties.Select(p => targetEntityType.FindProperty(p.Name)).ToList(),
- targetPrincipalEntityType.FindKey(
- foreignKey.PrincipalKey.Properties.Select(p => targetPrincipalEntityType.FindProperty(p.Name)).ToList()),
- targetPrincipalEntityType);
- clonedForeignKey.IsUnique = foreignKey.IsUnique;
- clonedForeignKey.IsRequired = foreignKey.IsRequired;
- foreignKey.GetAnnotations().ForEach(annotation => clonedForeignKey[annotation.Name] = annotation.Value);
- }
- }
-
- private static void CloneNavigations(IReadOnlyEntityType sourceEntityType, IMutableEntityType targetEntityType)
- {
- foreach (var navigation in sourceEntityType.GetDeclaredNavigations())
- {
- var targetDependentEntityType = targetEntityType.Model.FindEntityType(navigation.ForeignKey.DeclaringEntityType.Name);
- var targetPrincipalEntityType = targetEntityType.Model.FindEntityType(navigation.ForeignKey.PrincipalEntityType.Name);
- var targetForeignKey = targetDependentEntityType.FindForeignKey(
- navigation.ForeignKey.Properties.Select(p => targetDependentEntityType.FindProperty(p.Name)).ToList(),
- targetPrincipalEntityType.FindKey(
- navigation.ForeignKey.PrincipalKey.Properties.Select(
- p => targetPrincipalEntityType.FindProperty(p.Name)).ToList()),
- targetPrincipalEntityType);
- var clonedNavigation = navigation.IsOnDependent
- ? (navigation.GetIdentifyingMemberInfo() != null
- ? targetForeignKey.SetDependentToPrincipal(navigation.GetIdentifyingMemberInfo())
- : targetForeignKey.SetDependentToPrincipal(navigation.Name))
- : (navigation.GetIdentifyingMemberInfo() != null
- ? targetForeignKey.SetPrincipalToDependent(navigation.GetIdentifyingMemberInfo())
- : targetForeignKey.SetPrincipalToDependent(navigation.Name));
- navigation.GetAnnotations().ForEach(annotation => clonedNavigation[annotation.Name] = annotation.Value);
- }
- }
}
diff --git a/test/EFCore.Specification.Tests/TestUtilities/NavigationComparer.cs b/test/EFCore.Specification.Tests/TestUtilities/NavigationComparer.cs
deleted file mode 100644
index eb4707da5de..00000000000
--- a/test/EFCore.Specification.Tests/TestUtilities/NavigationComparer.cs
+++ /dev/null
@@ -1,33 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-namespace Microsoft.EntityFrameworkCore.TestUtilities;
-
-public class NavigationComparer : IEqualityComparer, IComparer
-{
- private readonly bool _compareAnnotations;
-
- public NavigationComparer(bool compareAnnotations = true)
- {
- _compareAnnotations = compareAnnotations;
- }
-
- public int Compare(IReadOnlyNavigation x, IReadOnlyNavigation y)
- => StringComparer.Ordinal.Compare(x.Name, y.Name);
-
- public bool Equals(IReadOnlyNavigation x, IReadOnlyNavigation y)
- {
- if (x == null)
- {
- return y == null;
- }
-
- return y == null
- ? false
- : x.Name == y.Name
- && (!_compareAnnotations || x.GetAnnotations().SequenceEqual(y.GetAnnotations(), AnnotationComparer.Instance));
- }
-
- public int GetHashCode(IReadOnlyNavigation obj)
- => obj.Name.GetHashCode();
-}
diff --git a/test/EFCore.Specification.Tests/TestUtilities/PropertyComparer.cs b/test/EFCore.Specification.Tests/TestUtilities/PropertyComparer.cs
deleted file mode 100644
index fae9745cec6..00000000000
--- a/test/EFCore.Specification.Tests/TestUtilities/PropertyComparer.cs
+++ /dev/null
@@ -1,40 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-namespace Microsoft.EntityFrameworkCore.TestUtilities;
-
-public class PropertyComparer : IEqualityComparer, IComparer
-{
- private readonly bool _compareAnnotations;
-
- public PropertyComparer(bool compareAnnotations = true)
- {
- _compareAnnotations = compareAnnotations;
- }
-
- public int Compare(IReadOnlyProperty x, IReadOnlyProperty y)
- => StringComparer.Ordinal.Compare(x.Name, y.Name);
-
- public bool Equals(IReadOnlyProperty x, IReadOnlyProperty y)
- {
- if (x == null)
- {
- return y == null;
- }
-
- return y == null
- ? false
- : x.Name == y.Name
- && x.ClrType == y.ClrType
- && x.IsShadowProperty() == y.IsShadowProperty()
- && x.IsNullable == y.IsNullable
- && x.IsConcurrencyToken == y.IsConcurrencyToken
- && x.ValueGenerated == y.ValueGenerated
- && x.GetBeforeSaveBehavior() == y.GetBeforeSaveBehavior()
- && x.GetAfterSaveBehavior() == y.GetAfterSaveBehavior()
- && (!_compareAnnotations || x.GetAnnotations().SequenceEqual(y.GetAnnotations(), AnnotationComparer.Instance));
- }
-
- public int GetHashCode(IReadOnlyProperty obj)
- => obj.Name.GetHashCode();
-}
diff --git a/test/EFCore.Specification.Tests/TestUtilities/AnnotationComparer.cs b/test/EFCore.Specification.Tests/TestUtilities/TestAnnotationComparer.cs
similarity index 81%
rename from test/EFCore.Specification.Tests/TestUtilities/AnnotationComparer.cs
rename to test/EFCore.Specification.Tests/TestUtilities/TestAnnotationComparer.cs
index bdc460e5ba1..8b546c4c520 100644
--- a/test/EFCore.Specification.Tests/TestUtilities/AnnotationComparer.cs
+++ b/test/EFCore.Specification.Tests/TestUtilities/TestAnnotationComparer.cs
@@ -6,11 +6,11 @@
// ReSharper disable PossibleNullReferenceException
namespace Microsoft.EntityFrameworkCore.TestUtilities;
-public class AnnotationComparer : IEqualityComparer, IComparer
+public class TestAnnotationComparer : IEqualityComparer, IComparer
{
- public static readonly AnnotationComparer Instance = new();
+ public static readonly TestAnnotationComparer Instance = new();
- private AnnotationComparer()
+ private TestAnnotationComparer()
{
}
diff --git a/test/EFCore.Specification.Tests/TestUtilities/TestIndexComparer.cs b/test/EFCore.Specification.Tests/TestUtilities/TestIndexComparer.cs
deleted file mode 100644
index 75ff2397f1a..00000000000
--- a/test/EFCore.Specification.Tests/TestUtilities/TestIndexComparer.cs
+++ /dev/null
@@ -1,36 +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 Microsoft.EntityFrameworkCore.Metadata.Internal;
-
-namespace Microsoft.EntityFrameworkCore.TestUtilities;
-
-public class TestIndexComparer : IEqualityComparer, IComparer
-{
- private readonly bool _compareAnnotations;
-
- public TestIndexComparer(bool compareAnnotations = true)
- {
- _compareAnnotations = compareAnnotations;
- }
-
- public int Compare(IReadOnlyIndex x, IReadOnlyIndex y)
- => PropertyListComparer.Instance.Compare(x.Properties, y.Properties);
-
- public bool Equals(IReadOnlyIndex x, IReadOnlyIndex y)
- {
- if (x == null)
- {
- return y == null;
- }
-
- return y == null
- ? false
- : PropertyListComparer.Instance.Equals(x.Properties, y.Properties)
- && x.IsUnique == y.IsUnique
- && (!_compareAnnotations || x.GetAnnotations().SequenceEqual(y.GetAnnotations(), AnnotationComparer.Instance));
- }
-
- public int GetHashCode(IReadOnlyIndex obj)
- => PropertyListComparer.Instance.GetHashCode(obj.Properties);
-}
diff --git a/test/EFCore.Specification.Tests/TestUtilities/TestKeyComparer.cs b/test/EFCore.Specification.Tests/TestUtilities/TestKeyComparer.cs
deleted file mode 100644
index a2e1b21e60e..00000000000
--- a/test/EFCore.Specification.Tests/TestUtilities/TestKeyComparer.cs
+++ /dev/null
@@ -1,35 +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 Microsoft.EntityFrameworkCore.Metadata.Internal;
-
-namespace Microsoft.EntityFrameworkCore.TestUtilities;
-
-public class TestKeyComparer : IEqualityComparer, IComparer
-{
- private readonly bool _compareAnnotations;
-
- public TestKeyComparer(bool compareAnnotations = true)
- {
- _compareAnnotations = compareAnnotations;
- }
-
- public int Compare(IReadOnlyKey x, IReadOnlyKey y)
- => PropertyListComparer.Instance.Compare(x.Properties, y.Properties);
-
- public bool Equals(IReadOnlyKey x, IReadOnlyKey y)
- {
- if (x == null)
- {
- return y == null;
- }
-
- return y == null
- ? false
- : PropertyListComparer.Instance.Equals(x.Properties, y.Properties)
- && (!_compareAnnotations || x.GetAnnotations().SequenceEqual(y.GetAnnotations(), AnnotationComparer.Instance));
- }
-
- public int GetHashCode(IReadOnlyKey obj)
- => PropertyListComparer.Instance.GetHashCode(obj.Properties);
-}
diff --git a/test/EFCore.SqlServer.Tests/ModelBuilding/SqlServerModelBuilderGenericTest.cs b/test/EFCore.SqlServer.Tests/ModelBuilding/SqlServerModelBuilderGenericTest.cs
index a49a0be0595..f5017e99315 100644
--- a/test/EFCore.SqlServer.Tests/ModelBuilding/SqlServerModelBuilderGenericTest.cs
+++ b/test/EFCore.SqlServer.Tests/ModelBuilding/SqlServerModelBuilderGenericTest.cs
@@ -8,64 +8,104 @@ namespace Microsoft.EntityFrameworkCore.ModelBuilding;
public class SqlServerModelBuilderGenericTest : SqlServerModelBuilderTestBase
{
- public class SqlServerGenericNonRelationship : SqlServerNonRelationship
+ public class SqlServerGenericNonRelationship : SqlServerNonRelationship, IClassFixture
{
+ public SqlServerGenericNonRelationship(SqlServerModelBuilderFixture fixture)
+ : base(fixture)
+ {
+ }
+
protected override TestModelBuilder CreateTestModelBuilder(
TestHelpers testHelpers,
Action? configure)
=> new ModelBuilderGenericTest.GenericTestModelBuilder(testHelpers, configure);
}
- public class SqlServerGenericComplexType : SqlServerComplexType
+ public class SqlServerGenericComplexType : SqlServerComplexType, IClassFixture
{
+ public SqlServerGenericComplexType(SqlServerModelBuilderFixture fixture)
+ : base(fixture)
+ {
+ }
+
protected override TestModelBuilder CreateTestModelBuilder(
TestHelpers testHelpers,
Action? configure)
=> new ModelBuilderGenericTest.GenericTestModelBuilder(testHelpers, configure);
}
- public class SqlServerGenericInheritance : SqlServerInheritance
+ public class SqlServerGenericInheritance : SqlServerInheritance, IClassFixture
{
+ public SqlServerGenericInheritance(SqlServerModelBuilderFixture fixture)
+ : base(fixture)
+ {
+ }
+
protected override TestModelBuilder CreateTestModelBuilder(
TestHelpers testHelpers,
Action? configure)
=> new ModelBuilderGenericTest.GenericTestModelBuilder(testHelpers, configure);
}
- public class SqlServerGenericOneToMany : SqlServerOneToMany
+ public class SqlServerGenericOneToMany : SqlServerOneToMany, IClassFixture
{
+ public SqlServerGenericOneToMany(SqlServerModelBuilderFixture fixture)
+ : base(fixture)
+ {
+ }
+
protected override TestModelBuilder CreateTestModelBuilder(
TestHelpers testHelpers,
Action? configure)
=> new ModelBuilderGenericTest.GenericTestModelBuilder(testHelpers, configure);
}
- public class SqlServerGenericManyToOne : SqlServerManyToOne
+ public class SqlServerGenericManyToOne : SqlServerManyToOne, IClassFixture
{
+ public SqlServerGenericManyToOne(SqlServerModelBuilderFixture fixture)
+ : base(fixture)
+ {
+ }
+
protected override TestModelBuilder CreateTestModelBuilder(
TestHelpers testHelpers,
Action? configure)
=> new ModelBuilderGenericTest.GenericTestModelBuilder(testHelpers, configure);
}
- public class SqlServerGenericOneToOne : SqlServerOneToOne
+ public class SqlServerGenericOneToOne : SqlServerOneToOne, IClassFixture
{
+ public SqlServerGenericOneToOne(SqlServerModelBuilderFixture fixture)
+ : base(fixture)
+ {
+ }
+
protected override TestModelBuilder CreateTestModelBuilder(
TestHelpers testHelpers,
Action? configure)
=> new ModelBuilderGenericTest.GenericTestModelBuilder(testHelpers, configure);
}
- public class SqlServerGenericManyToMany : SqlServerManyToMany
+ public class SqlServerGenericManyToMany : SqlServerManyToMany, IClassFixture
{
+ public SqlServerGenericManyToMany(SqlServerModelBuilderFixture fixture)
+ : base(fixture)
+ {
+ }
+
protected override TestModelBuilder CreateTestModelBuilder(
TestHelpers testHelpers,
Action? configure)
=> new ModelBuilderGenericTest.GenericTestModelBuilder(testHelpers, configure);
}
- public class SqlServerGenericOwnedTypes : SqlServerOwnedTypes
+ public class SqlServerGenericOwnedTypes : SqlServerOwnedTypes, IClassFixture
{
+ public SqlServerGenericOwnedTypes(SqlServerModelBuilderFixture fixture)
+ : base(fixture)
+ {
+ }
+
protected override TestModelBuilder CreateTestModelBuilder(
TestHelpers testHelpers,
Action? configure)
diff --git a/test/EFCore.SqlServer.Tests/ModelBuilding/SqlServerModelBuilderNonGenericTest.cs b/test/EFCore.SqlServer.Tests/ModelBuilding/SqlServerModelBuilderNonGenericTest.cs
index 37d8f51cea6..8597c0d254d 100644
--- a/test/EFCore.SqlServer.Tests/ModelBuilding/SqlServerModelBuilderNonGenericTest.cs
+++ b/test/EFCore.SqlServer.Tests/ModelBuilding/SqlServerModelBuilderNonGenericTest.cs
@@ -8,64 +8,104 @@ namespace Microsoft.EntityFrameworkCore.ModelBuilding;
public class SqlServerModelBuilderNonGenericTest : SqlServerModelBuilderTestBase
{
- public class SqlServerNonGenericNonRelationship : SqlServerNonRelationship
+ public class SqlServerNonGenericNonRelationship : SqlServerNonRelationship, IClassFixture
{
+ public SqlServerNonGenericNonRelationship(SqlServerModelBuilderFixture fixture)
+ : base(fixture)
+ {
+ }
+
protected override TestModelBuilder CreateTestModelBuilder(
TestHelpers testHelpers,
Action? configure)
=> new ModelBuilderNonGenericTest.NonGenericTestModelBuilder(testHelpers, configure);
}
- public class SqlServerNonGenericComplexType : SqlServerComplexType
+ public class SqlServerNonGenericComplexType : SqlServerComplexType, IClassFixture
{
+ public SqlServerNonGenericComplexType(SqlServerModelBuilderFixture fixture)
+ : base(fixture)
+ {
+ }
+
protected override TestModelBuilder CreateTestModelBuilder(
TestHelpers testHelpers,
Action? configure)
=> new ModelBuilderNonGenericTest.NonGenericTestModelBuilder(testHelpers, configure);
}
- public class SqlServerNonGenericInheritance : SqlServerInheritance
+ public class SqlServerNonGenericInheritance : SqlServerInheritance, IClassFixture
{
+ public SqlServerNonGenericInheritance(SqlServerModelBuilderFixture fixture)
+ : base(fixture)
+ {
+ }
+
protected override TestModelBuilder CreateTestModelBuilder(
TestHelpers testHelpers,
Action? configure)
=> new ModelBuilderNonGenericTest.NonGenericTestModelBuilder(testHelpers, configure);
}
- public class SqlServerNonGenericOneToMany : SqlServerOneToMany
+ public class SqlServerNonGenericOneToMany : SqlServerOneToMany, IClassFixture
{
+ public SqlServerNonGenericOneToMany(SqlServerModelBuilderFixture fixture)
+ : base(fixture)
+ {
+ }
+
protected override TestModelBuilder CreateTestModelBuilder(
TestHelpers testHelpers,
Action? configure)
=> new ModelBuilderNonGenericTest.NonGenericTestModelBuilder(testHelpers, configure);
}
- public class SqlServerNonGenericManyToOne : SqlServerManyToOne
+ public class SqlServerNonGenericManyToOne : SqlServerManyToOne, IClassFixture
{
+ public SqlServerNonGenericManyToOne(SqlServerModelBuilderFixture fixture)
+ : base(fixture)
+ {
+ }
+
protected override TestModelBuilder CreateTestModelBuilder(
TestHelpers testHelpers,
Action? configure)
=> new ModelBuilderNonGenericTest.NonGenericTestModelBuilder(testHelpers, configure);
}
- public class SqlServerNonGenericOneToOne : SqlServerOneToOne
+ public class SqlServerNonGenericOneToOne : SqlServerOneToOne, IClassFixture
{
+ public SqlServerNonGenericOneToOne(SqlServerModelBuilderFixture fixture)
+ : base(fixture)
+ {
+ }
+
protected override TestModelBuilder CreateTestModelBuilder(
TestHelpers testHelpers,
Action? configure)
=> new ModelBuilderNonGenericTest.NonGenericTestModelBuilder(testHelpers, configure);
}
- public class SqlServerNonGenericManyToMany : SqlServerManyToMany
+ public class SqlServerNonGenericManyToMany : SqlServerManyToMany, IClassFixture
{
+ public SqlServerNonGenericManyToMany(SqlServerModelBuilderFixture fixture)
+ : base(fixture)
+ {
+ }
+
protected override TestModelBuilder CreateTestModelBuilder(
TestHelpers testHelpers,
Action? configure)
=> new ModelBuilderNonGenericTest.NonGenericTestModelBuilder(testHelpers, configure);
}
- public class SqlServerNonGenericOwnedTypes : SqlServerOwnedTypes
+ public class SqlServerNonGenericOwnedTypes : SqlServerOwnedTypes, IClassFixture
{
+ public SqlServerNonGenericOwnedTypes(SqlServerModelBuilderFixture fixture)
+ : base(fixture)
+ {
+ }
+
protected override TestModelBuilder CreateTestModelBuilder(
TestHelpers testHelpers,
Action? configure)
diff --git a/test/EFCore.SqlServer.Tests/ModelBuilding/SqlServerModelBuilderTestBase.cs b/test/EFCore.SqlServer.Tests/ModelBuilding/SqlServerModelBuilderTestBase.cs
index 272dee06cd2..df2f45112da 100644
--- a/test/EFCore.SqlServer.Tests/ModelBuilding/SqlServerModelBuilderTestBase.cs
+++ b/test/EFCore.SqlServer.Tests/ModelBuilding/SqlServerModelBuilderTestBase.cs
@@ -9,8 +9,13 @@ namespace Microsoft.EntityFrameworkCore.ModelBuilding;
public class SqlServerModelBuilderTestBase : RelationalModelBuilderTest
{
- public abstract class SqlServerNonRelationship : RelationalNonRelationshipTestBase
+ public abstract class SqlServerNonRelationship : RelationalNonRelationshipTestBase, IClassFixture
{
+ public SqlServerNonRelationship(SqlServerModelBuilderFixture fixture)
+ : base(fixture)
+ {
+ }
+
[ConditionalFact]
public virtual void Index_has_a_filter_if_nonclustered_unique_with_nullable_properties()
{
@@ -269,14 +274,24 @@ protected override TestModelBuilder CreateModelBuilder(Action CreateTestModelBuilder(SqlServerTestHelpers.Instance, configure);
}
- public abstract class SqlServerComplexType : RelationalComplexTypeTestBase
+ public abstract class SqlServerComplexType : RelationalComplexTypeTestBase, IClassFixture
{
+ public SqlServerComplexType(SqlServerModelBuilderFixture fixture)
+ : base(fixture)
+ {
+ }
+
protected override TestModelBuilder CreateModelBuilder(Action? configure = null)
=> CreateTestModelBuilder(SqlServerTestHelpers.Instance, configure);
}
- public abstract class SqlServerInheritance : RelationalInheritanceTestBase
+ public abstract class SqlServerInheritance : RelationalInheritanceTestBase, IClassFixture
{
+ public SqlServerInheritance(SqlServerModelBuilderFixture fixture)
+ : base(fixture)
+ {
+ }
+
[ConditionalFact] // #7240
public void Can_use_shadow_FK_that_collides_with_convention_shadow_FK_on_other_derived_type()
{
@@ -625,8 +640,13 @@ public class DisjointChildSubclass2 : Child
}
}
- public abstract class SqlServerOneToMany : RelationalOneToManyTestBase
+ public abstract class SqlServerOneToMany : RelationalOneToManyTestBase, IClassFixture
{
+ public SqlServerOneToMany(SqlServerModelBuilderFixture fixture)
+ : base(fixture)
+ {
+ }
+
[ConditionalFact]
public virtual void Shadow_foreign_keys_to_generic_types_have_terrible_names_that_should_not_change()
{
@@ -687,20 +707,35 @@ protected override TestModelBuilder CreateModelBuilder(Action CreateTestModelBuilder(SqlServerTestHelpers.Instance, configure);
}
- public abstract class SqlServerManyToOne : RelationalManyToOneTestBase
+ public abstract class SqlServerManyToOne : RelationalManyToOneTestBase, IClassFixture
{
+ public SqlServerManyToOne(SqlServerModelBuilderFixture fixture)
+ : base(fixture)
+ {
+ }
+
protected override TestModelBuilder CreateModelBuilder(Action? configure = null)
=> CreateTestModelBuilder(SqlServerTestHelpers.Instance, configure);
}
- public abstract class SqlServerOneToOne : RelationalOneToOneTestBase
+ public abstract class SqlServerOneToOne : RelationalOneToOneTestBase, IClassFixture
{
+ public SqlServerOneToOne(SqlServerModelBuilderFixture fixture)
+ : base(fixture)
+ {
+ }
+
protected override TestModelBuilder CreateModelBuilder(Action? configure = null)
=> CreateTestModelBuilder(SqlServerTestHelpers.Instance, configure);
}
- public abstract class SqlServerManyToMany : RelationalManyToManyTestBase
+ public abstract class SqlServerManyToMany : RelationalManyToManyTestBase, IClassFixture
{
+ public SqlServerManyToMany(SqlServerModelBuilderFixture fixture)
+ : base(fixture)
+ {
+ }
+
[ConditionalFact]
public virtual void Join_entity_type_uses_same_schema()
{
@@ -761,8 +796,13 @@ protected override TestModelBuilder CreateModelBuilder(Action CreateTestModelBuilder(SqlServerTestHelpers.Instance, configure);
}
- public abstract class SqlServerOwnedTypes : RelationalOwnedTypesTestBase
+ public abstract class SqlServerOwnedTypes : RelationalOwnedTypesTestBase, IClassFixture
{
+ public SqlServerOwnedTypes(SqlServerModelBuilderFixture fixture)
+ : base(fixture)
+ {
+ }
+
[ConditionalFact]
public virtual void Owned_types_use_table_splitting_by_default()
{
@@ -2157,6 +2197,10 @@ protected override TestModelBuilder CreateModelBuilder(Action CreateTestModelBuilder(SqlServerTestHelpers.Instance, configure);
}
+ public class SqlServerModelBuilderFixture : RelationalModelBuilderFixture
+ {
+ }
+
public abstract class TestTemporalTableBuilder
where TEntity : class
{
diff --git a/test/EFCore.Tests/ModelBuilding/ComplexTypeTestBase.cs b/test/EFCore.Tests/ModelBuilding/ComplexTypeTestBase.cs
index 092cfad9c44..c75ae5e9844 100644
--- a/test/EFCore.Tests/ModelBuilding/ComplexTypeTestBase.cs
+++ b/test/EFCore.Tests/ModelBuilding/ComplexTypeTestBase.cs
@@ -12,6 +12,11 @@ public abstract partial class ModelBuilderTest
{
public abstract class ComplexTypeTestBase : ModelBuilderTestBase
{
+ public ComplexTypeTestBase(ModelBuilderFixtureBase fixture)
+ : base(fixture)
+ {
+ }
+
[ConditionalFact]
public virtual void Can_set_complex_property_annotation()
{
@@ -475,6 +480,8 @@ public virtual void Access_mode_can_be_overridden_at_entity_and_property_levels(
});
var model = modelBuilder.FinalizeModel();
+ AssertEqual(modelBuilder.Model, model);
+
var entityType = model.FindEntityType(typeof(ComplexProperties))!;
Assert.Equal(PropertyAccessMode.Field, model.GetPropertyAccessMode());
@@ -1595,6 +1602,7 @@ public virtual void Complex_properties_not_discovered_by_convention()
});
var model = modelBuilder.FinalizeModel();
+ AssertEqual(modelBuilder.Model, model);
var customerType = model.FindEntityType(typeof(ComplexProperties))!
.FindComplexProperty(nameof(ComplexProperties.Customer))!.ComplexType;
diff --git a/test/EFCore.Tests/ModelBuilding/InheritanceTestBase.cs b/test/EFCore.Tests/ModelBuilding/InheritanceTestBase.cs
index 5e5cd24dea5..70ad44cf5ee 100644
--- a/test/EFCore.Tests/ModelBuilding/InheritanceTestBase.cs
+++ b/test/EFCore.Tests/ModelBuilding/InheritanceTestBase.cs
@@ -12,6 +12,11 @@ public abstract partial class ModelBuilderTest
{
public abstract class InheritanceTestBase : ModelBuilderTestBase
{
+ public InheritanceTestBase(ModelBuilderFixtureBase fixture)
+ : base(fixture)
+ {
+ }
+
[ConditionalFact]
public virtual void Can_map_derived_types_first()
{
@@ -129,8 +134,8 @@ public virtual void Can_set_and_remove_base_type()
modelBuilder.Entity().Ignore(b => b.Bun);
Assert.Null(pickle.BaseType);
- var pickleClone = modelBuilder.Model.Clone().FindEntityType(pickle.Name);
- var initialProperties = pickleClone.GetProperties().Where(p => p.Name != "__jObject").ToList();
+ var pickleClone = Clone(modelBuilder.Model).FindEntityType(pickle.Name);
+ var initialProperties = pickleClone.GetProperties().ToList();
var initialKeys = pickleClone.GetKeys().ToList();
var initialIndexes = pickleClone.GetIndexes().ToList();
var initialForeignKeys = pickleClone.GetForeignKeys().ToList();
@@ -142,35 +147,33 @@ public virtual void Can_set_and_remove_base_type()
Assert.Same(typeof(Ingredient), pickle.BaseType.ClrType);
- var actualProperties = pickle.GetProperties().Where(p => p.Name != "__jObject").ToList();
- AssertEqual(
+ var actualProperties = pickle.GetProperties();
+ Fixture.AssertEqual(
initialProperties.Where(p => p.Name != "Discriminator"),
- actualProperties.Where(p => p.Name != "Discriminator"),
- new PropertyComparer(compareAnnotations: false));
+ actualProperties.Where(p => p.Name != "Discriminator"));
- AssertEqual(initialKeys, pickle.GetKeys());
- AssertEqual(initialIndexes, pickle.GetIndexes());
- AssertEqual(initialForeignKeys, pickle.GetForeignKeys());
- AssertEqual(initialReferencingForeignKeys, pickle.GetReferencingForeignKeys());
+ Fixture.AssertEqual(initialKeys, pickle.GetKeys());
+ Fixture.AssertEqual(initialIndexes, pickle.GetIndexes());
+ Fixture.AssertEqual(initialForeignKeys, pickle.GetForeignKeys());
+ Fixture.AssertEqual(initialReferencingForeignKeys, pickle.GetReferencingForeignKeys());
pickleBuilder.HasBaseType(null);
Assert.Null(pickle.BaseType);
- actualProperties = pickle.GetProperties().Where(p => p.Name != "__jObject").ToList();
- AssertEqual(initialProperties, actualProperties, new PropertyComparer(compareAnnotations: false));
- AssertEqual(initialKeys, pickle.GetKeys());
- AssertEqual(initialIndexes, pickle.GetIndexes());
- AssertEqual(initialForeignKeys, pickle.GetForeignKeys());
- AssertEqual(initialReferencingForeignKeys, pickle.GetReferencingForeignKeys());
-
- actualProperties = ingredient.GetProperties().Where(p => p.Name != "__jObject").ToList();
- AssertEqual(
+ actualProperties = pickle.GetProperties();
+ Fixture.AssertEqual(initialProperties, actualProperties);
+ Fixture.AssertEqual(initialKeys, pickle.GetKeys());
+ Fixture.AssertEqual(initialIndexes, pickle.GetIndexes());
+ Fixture.AssertEqual(initialForeignKeys, pickle.GetForeignKeys());
+ Fixture.AssertEqual(initialReferencingForeignKeys, pickle.GetReferencingForeignKeys());
+
+ actualProperties = ingredient.GetProperties();
+ Fixture.AssertEqual(
initialProperties.Where(p => p.Name != "Discriminator"),
- actualProperties.Where(p => p.Name != "Discriminator"),
- new PropertyComparer(compareAnnotations: false));
+ actualProperties.Where(p => p.Name != "Discriminator"));
- AssertEqual(initialKeys, ingredient.GetKeys());
- AssertEqual(initialIndexes, ingredient.GetIndexes());
+ Fixture.AssertEqual(initialKeys, ingredient.GetKeys());
+ Fixture.AssertEqual(initialIndexes, ingredient.GetIndexes());
Assert.Equal(initialForeignKeys.Count(), ingredient.GetForeignKeys().Count());
Assert.Equal(initialReferencingForeignKeys.Count(), ingredient.GetReferencingForeignKeys().Count());
}
@@ -584,7 +587,7 @@ public virtual void Index_removed_when_covered_by_an_inherited_foreign_key()
Assert.False(derivedDependentEntityType.GetDeclaredForeignKeys().Single().IsUnique);
Assert.Empty(derivedDependentEntityType.GetDeclaredIndexes());
- var backOrderClone = modelBuilder.Model.Clone().FindEntityType(derivedDependentEntityType.Name);
+ var backOrderClone = Clone(modelBuilder.Model).FindEntityType(derivedDependentEntityType.Name);
var initialProperties = backOrderClone.GetProperties().ToList();
var initialKeys = backOrderClone.GetKeys().ToList();
var initialIndexes = backOrderClone.GetIndexes().ToList();
@@ -603,10 +606,10 @@ public virtual void Index_removed_when_covered_by_an_inherited_foreign_key()
Assert.Single(dependentEntityType.GetIndexes());
Assert.False(dependentEntityType.FindIndex(fk.Properties).IsUnique);
- AssertEqual(initialProperties, derivedDependentEntityType.GetProperties(), new PropertyComparer(compareAnnotations: false));
- AssertEqual(initialKeys, derivedDependentEntityType.GetKeys());
- AssertEqual(initialIndexes, derivedDependentEntityType.GetIndexes());
- AssertEqual(initialForeignKeys, derivedDependentEntityType.GetForeignKeys());
+ Fixture.AssertEqual(initialProperties, derivedDependentEntityType.GetProperties());
+ Fixture.AssertEqual(initialKeys, derivedDependentEntityType.GetKeys());
+ Fixture.AssertEqual(initialIndexes, derivedDependentEntityType.GetIndexes());
+ Fixture.AssertEqual(initialForeignKeys, derivedDependentEntityType.GetForeignKeys());
principalEntityBuilder.HasOne().WithOne()
.HasPrincipalKey(
@@ -661,7 +664,7 @@ public virtual void Index_removed_when_covered_by_an_inherited_index()
Assert.False(derivedDependentEntityType.GetDeclaredForeignKeys().Single().IsUnique);
Assert.Empty(derivedDependentEntityType.GetDeclaredIndexes());
- var backOrderClone = modelBuilder.Model.Clone().FindEntityType(derivedDependentEntityType.Name);
+ var backOrderClone = Clone(modelBuilder.Model).FindEntityType(derivedDependentEntityType.Name);
var initialProperties = backOrderClone.GetProperties().ToList();
var initialKeys = backOrderClone.GetKeys().ToList();
var initialIndexes = backOrderClone.GetIndexes().ToList();
@@ -690,10 +693,10 @@ public virtual void Index_removed_when_covered_by_an_inherited_index()
Assert.False(derivedDependentEntityType.GetDeclaredForeignKeys().Single().IsUnique);
Assert.Empty(derivedDependentEntityType.GetDeclaredIndexes());
- AssertEqual(initialProperties, derivedDependentEntityType.GetProperties());
- AssertEqual(initialKeys, derivedDependentEntityType.GetKeys());
- AssertEqual(initialIndexes, derivedDependentEntityType.GetIndexes());
- AssertEqual(initialForeignKeys, derivedDependentEntityType.GetForeignKeys());
+ Fixture.AssertEqual(initialProperties, derivedDependentEntityType.GetProperties());
+ Fixture.AssertEqual(initialKeys, derivedDependentEntityType.GetKeys());
+ Fixture.AssertEqual(initialIndexes, derivedDependentEntityType.GetIndexes());
+ Fixture.AssertEqual(initialForeignKeys, derivedDependentEntityType.GetForeignKeys());
}
[ConditionalFact]
diff --git a/test/EFCore.Tests/ModelBuilding/ManyToManyTestBase.cs b/test/EFCore.Tests/ModelBuilding/ManyToManyTestBase.cs
index b9f136e5026..4a4a29c2468 100644
--- a/test/EFCore.Tests/ModelBuilding/ManyToManyTestBase.cs
+++ b/test/EFCore.Tests/ModelBuilding/ManyToManyTestBase.cs
@@ -13,6 +13,11 @@ public abstract partial class ModelBuilderTest
{
public abstract class ManyToManyTestBase : ModelBuilderTestBase
{
+ public ManyToManyTestBase(ModelBuilderFixtureBase fixture)
+ : base(fixture)
+ {
+ }
+
[ConditionalFact]
public virtual void Discovers_navigations()
{
@@ -1025,7 +1030,7 @@ public virtual void Can_use_implicit_shared_type_with_implicit_relationships_as_
Assert.Equal(
CoreStrings.ClashingSharedType(typeof(Dictionary).ShortDisplayName()),
- Assert.Throws(() => modelBuilder.Entity>()).Message);
+ Assert.Throws(modelBuilder.Entity>).Message);
modelBuilder.FinalizeModel();
}
@@ -1086,9 +1091,9 @@ public virtual void Can_use_implicit_shared_type_with_default_name_and_implicit_
Assert.Equal(
CoreStrings.ClashingSharedType(typeof(Dictionary).ShortDisplayName()),
- Assert.Throws(() => modelBuilder.Entity>()).Message);
+ Assert.Throws(modelBuilder.Entity>).Message);
- modelBuilder.FinalizeModel();
+ AssertEqual(modelBuilder.Model, modelBuilder.FinalizeModel());
}
[ConditionalFact]
diff --git a/test/EFCore.Tests/ModelBuilding/ManyToOneTestBase.cs b/test/EFCore.Tests/ModelBuilding/ManyToOneTestBase.cs
index 535a8587f5a..a0e34fe7d36 100644
--- a/test/EFCore.Tests/ModelBuilding/ManyToOneTestBase.cs
+++ b/test/EFCore.Tests/ModelBuilding/ManyToOneTestBase.cs
@@ -7,8 +7,13 @@ namespace Microsoft.EntityFrameworkCore.ModelBuilding;
public abstract partial class ModelBuilderTest
{
- public abstract class ManyToOneTestBase : ModelBuilderTestBase
+ public abstract class ManyToOneTestBase: ModelBuilderTestBase
{
+ public ManyToOneTestBase(ModelBuilderFixtureBase fixture)
+ : base(fixture)
+ {
+ }
+
[ConditionalFact]
public virtual void Finds_existing_navigations_and_uses_associated_FK()
{
@@ -886,7 +891,6 @@ public virtual void Can_use_non_PK_principal()
Assert.Same(principalKey, principalType.FindPrimaryKey());
Assert.Same(dependentKey, dependentType.FindPrimaryKey());
- expectedPrincipalProperties.Add(fk.PrincipalKey.Properties.Single());
AssertEqual(expectedPrincipalProperties, principalType.GetProperties());
expectedDependentProperties.Add(fk.Properties.Single());
AssertEqual(expectedDependentProperties, dependentType.GetProperties());
@@ -1019,9 +1023,7 @@ public virtual void Can_have_FK_by_convention_specified_with_explicit_principal_
Assert.Contains(fk.PrincipalKey, principalType.GetKeys());
Assert.NotSame(principalKey, fk.PrincipalKey);
- expectedPrincipalProperties.Add(fk.PrincipalKey.Properties.Single());
AssertEqual(expectedPrincipalProperties, principalType.GetProperties());
- expectedDependentProperties.Add(fk.Properties.Single());
AssertEqual(expectedDependentProperties, dependentType.GetProperties());
Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count());
@@ -1068,9 +1070,7 @@ public virtual void Can_have_FK_by_convention_specified_with_explicit_principal_
Assert.Contains(fk.PrincipalKey, principalType.GetKeys());
Assert.NotSame(principalKey, fk.PrincipalKey);
- expectedPrincipalProperties.Add(fk.PrincipalKey.Properties.Single());
AssertEqual(expectedPrincipalProperties, principalType.GetProperties());
- expectedDependentProperties.Add(fk.Properties.Single());
AssertEqual(expectedDependentProperties, dependentType.GetProperties());
Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count());
@@ -1688,7 +1688,7 @@ public virtual void Removes_existing_unidirectional_one_to_one_relationship()
// so now the RelationshipDiscoveryConvention should be able
// to unambiguously and automatically match up Nob.Hob and Hob.Nobs
var oldFk = principalType.GetForeignKeys().Single();
- AssertEqual(new[] { nameof(Nob.HobId1), nameof(Nob.HobId2) }, oldFk.Properties.Select(p => p.Name));
+ Assert.Equal(new[] { nameof(Nob.HobId1), nameof(Nob.HobId2) }, oldFk.Properties.Select(p => p.Name));
Assert.Same(oldFk, dependentType.GetNavigations().Single(n => n.Name == nameof(Hob.Nobs)).ForeignKey);
Assert.Same(oldFk, principalType.GetNavigations().Single(n => n.Name == nameof(Nob.Hob)).ForeignKey);
Assert.False(oldFk.IsUnique);
diff --git a/test/EFCore.Tests/ModelBuilding/ModelBuilderGenericRelationshipStringTest.cs b/test/EFCore.Tests/ModelBuilding/ModelBuilderGenericRelationshipStringTest.cs
index 53f70f1a0a9..8cf02430aa4 100644
--- a/test/EFCore.Tests/ModelBuilding/ModelBuilderGenericRelationshipStringTest.cs
+++ b/test/EFCore.Tests/ModelBuilding/ModelBuilderGenericRelationshipStringTest.cs
@@ -9,6 +9,11 @@ public class ModelBuilderGenericRelationshipStringTest : ModelBuilderGenericTest
{
public class GenericOneToManyString : OneToManyTestBase
{
+ public GenericOneToManyString(ModelBuilderFixtureBase fixture)
+ : base(fixture)
+ {
+ }
+
protected override TestModelBuilder CreateTestModelBuilder(
TestHelpers testHelpers,
Action? configure)
@@ -17,6 +22,10 @@ protected override TestModelBuilder CreateTestModelBuilder(
public class GenericManyToOneString : ManyToOneTestBase
{
+ public GenericManyToOneString(ModelBuilderFixtureBase fixture)
+ : base(fixture)
+ {
+ }
protected override TestModelBuilder CreateTestModelBuilder(
TestHelpers testHelpers,
Action? configure)
@@ -25,6 +34,10 @@ protected override TestModelBuilder CreateTestModelBuilder(
public class GenericManyToManyString : ManyToManyTestBase
{
+ public GenericManyToManyString(ModelBuilderFixtureBase fixture)
+ : base(fixture)
+ {
+ }
protected override TestModelBuilder CreateTestModelBuilder(
TestHelpers testHelpers,
Action? configure)
@@ -33,6 +46,10 @@ protected override TestModelBuilder CreateTestModelBuilder(
public class GenericOneToOneString : OneToOneTestBase
{
+ public GenericOneToOneString(ModelBuilderFixtureBase fixture)
+ : base(fixture)
+ {
+ }
protected override TestModelBuilder CreateTestModelBuilder(
TestHelpers testHelpers,
Action? configure)
@@ -41,6 +58,11 @@ protected override TestModelBuilder CreateTestModelBuilder(
public class GenericOwnedTypesString : OwnedTypesTestBase
{
+ public GenericOwnedTypesString(ModelBuilderFixtureBase fixture)
+ : base(fixture)
+ {
+ }
+
protected override TestModelBuilder CreateTestModelBuilder(
TestHelpers testHelpers,
Action? configure)
diff --git a/test/EFCore.Tests/ModelBuilding/ModelBuilderGenericRelationshipTypeTest.cs b/test/EFCore.Tests/ModelBuilding/ModelBuilderGenericRelationshipTypeTest.cs
index 823b04165ea..ad9e217b3cd 100644
--- a/test/EFCore.Tests/ModelBuilding/ModelBuilderGenericRelationshipTypeTest.cs
+++ b/test/EFCore.Tests/ModelBuilding/ModelBuilderGenericRelationshipTypeTest.cs
@@ -9,6 +9,11 @@ public class ModelBuilderGenericRelationshipTypeTest : ModelBuilderGenericTest
{
public class GenericOneToOneType : OneToOneTestBase
{
+ public GenericOneToOneType(ModelBuilderFixtureBase fixture)
+ : base(fixture)
+ {
+ }
+
protected override TestModelBuilder CreateTestModelBuilder(
TestHelpers testHelpers,
Action? configure)
@@ -17,6 +22,11 @@ protected override TestModelBuilder CreateTestModelBuilder(
public class GenericNonRelationshipTest : NonRelationshipTestBase
{
+ public GenericNonRelationshipTest(ModelBuilderFixtureBase fixture)
+ : base(fixture)
+ {
+ }
+
protected override TestModelBuilder CreateTestModelBuilder(
TestHelpers testHelpers,
Action? configure)
diff --git a/test/EFCore.Tests/ModelBuilding/ModelBuilderGenericTest.cs b/test/EFCore.Tests/ModelBuilding/ModelBuilderGenericTest.cs
index 8192897ba61..0024ac8eea6 100644
--- a/test/EFCore.Tests/ModelBuilding/ModelBuilderGenericTest.cs
+++ b/test/EFCore.Tests/ModelBuilding/ModelBuilderGenericTest.cs
@@ -47,6 +47,11 @@ public void Can_discover_large_models_through_navigations()
public class GenericNonRelationship : NonRelationshipTestBase
{
+ public GenericNonRelationship(ModelBuilderFixtureBase fixture)
+ : base(fixture)
+ {
+ }
+
protected override TestModelBuilder CreateTestModelBuilder(
TestHelpers testHelpers,
Action? configure)
@@ -68,6 +73,11 @@ public virtual void Changing_propertyInfo_updates_Property()
public class GenericComplexType : ComplexTypeTestBase
{
+ public GenericComplexType(ModelBuilderFixtureBase fixture)
+ : base(fixture)
+ {
+ }
+
protected override TestModelBuilder CreateTestModelBuilder(
TestHelpers testHelpers,
Action? configure)
@@ -92,14 +102,24 @@ public virtual void Changing_propertyInfo_updates_Property()
public class GenericInheritance : InheritanceTestBase
{
+ public GenericInheritance(ModelBuilderFixtureBase fixture)
+ : base(fixture)
+ {
+ }
+
protected override TestModelBuilder CreateTestModelBuilder(
TestHelpers testHelpers,
Action? configure)
=> new GenericTestModelBuilder(testHelpers, configure);
}
- public class GenericOwnedTypes : OwnedTypesTestBase
+ public class GenericOwnedTypes: OwnedTypesTestBase
{
+ public GenericOwnedTypes(ModelBuilderFixtureBase fixture)
+ : base(fixture)
+ {
+ }
+
protected override TestModelBuilder CreateTestModelBuilder(
TestHelpers testHelpers,
Action? configure)
@@ -108,6 +128,11 @@ protected override TestModelBuilder CreateTestModelBuilder(
public class GenericOneToMany : OneToManyTestBase
{
+ public GenericOneToMany(ModelBuilderFixtureBase fixture)
+ : base(fixture)
+ {
+ }
+
protected override TestModelBuilder CreateTestModelBuilder(
TestHelpers testHelpers,
Action? configure)
@@ -116,6 +141,11 @@ protected override TestModelBuilder CreateTestModelBuilder(
public class GenericManyToOne : ManyToOneTestBase
{
+ public GenericManyToOne(ModelBuilderFixtureBase fixture)
+ : base(fixture)
+ {
+ }
+
protected override TestModelBuilder CreateTestModelBuilder(
TestHelpers testHelpers,
Action? configure)
@@ -124,6 +154,11 @@ protected override TestModelBuilder CreateTestModelBuilder(
public class GenericManyToMany : ManyToManyTestBase
{
+ public GenericManyToMany(ModelBuilderFixtureBase fixture)
+ : base(fixture)
+ {
+ }
+
protected override TestModelBuilder CreateTestModelBuilder(
TestHelpers testHelpers,
Action? configure)
@@ -132,6 +167,11 @@ protected override TestModelBuilder CreateTestModelBuilder(
public class GenericOneToOne : OneToOneTestBase
{
+ public GenericOneToOne(ModelBuilderFixtureBase fixture)
+ : base(fixture)
+ {
+ }
+
protected override TestModelBuilder CreateTestModelBuilder(
TestHelpers testHelpers,
Action? configure)
diff --git a/test/EFCore.Tests/ModelBuilding/ModelBuilderNonGenericStringTest.cs b/test/EFCore.Tests/ModelBuilding/ModelBuilderNonGenericStringTest.cs
index 7370d0dcbba..711b77f3794 100644
--- a/test/EFCore.Tests/ModelBuilding/ModelBuilderNonGenericStringTest.cs
+++ b/test/EFCore.Tests/ModelBuilding/ModelBuilderNonGenericStringTest.cs
@@ -13,6 +13,11 @@ public class ModelBuilderNonGenericStringTest : ModelBuilderNonGenericTest
{
public class NonGenericStringOwnedTypes : OwnedTypesTestBase
{
+ public NonGenericStringOwnedTypes(ModelBuilderFixtureBase fixture)
+ : base(fixture)
+ {
+ }
+
protected override TestModelBuilder CreateTestModelBuilder(
TestHelpers testHelpers,
Action? configure)
@@ -24,11 +29,16 @@ public override void OwnedType_can_derive_from_Collection()
CoreStrings.AmbiguousSharedTypeEntityTypeName(
"Microsoft.EntityFrameworkCore.ModelBuilding.ModelBuilderTest+DependentEntity"),
Assert.Throws(
- () => base.OwnedType_can_derive_from_Collection()).Message);
+ base.OwnedType_can_derive_from_Collection).Message);
}
public class NonGenericStringOneToManyType : OneToManyTestBase
{
+ public NonGenericStringOneToManyType(ModelBuilderFixtureBase fixture)
+ : base(fixture)
+ {
+ }
+
protected override TestModelBuilder CreateTestModelBuilder(
TestHelpers testHelpers,
Action? configure)
@@ -42,6 +52,11 @@ public override void WithMany_pointing_to_keyless_entity_throws()
public class NonGenericStringManyToOneType : ManyToOneTestBase
{
+ public NonGenericStringManyToOneType(ModelBuilderFixtureBase fixture)
+ : base(fixture)
+ {
+ }
+
protected override TestModelBuilder CreateTestModelBuilder(
TestHelpers testHelpers,
Action? configure)
@@ -50,6 +65,11 @@ protected override TestModelBuilder CreateTestModelBuilder(
public class NonGenericStringOneToOneType : OneToOneTestBase
{
+ public NonGenericStringOneToOneType(ModelBuilderFixtureBase fixture)
+ : base(fixture)
+ {
+ }
+
protected override TestModelBuilder CreateTestModelBuilder(
TestHelpers testHelpers,
Action? configure)
diff --git a/test/EFCore.Tests/ModelBuilding/ModelBuilderNonGenericTest.cs b/test/EFCore.Tests/ModelBuilding/ModelBuilderNonGenericTest.cs
index d59a6c6d47d..4f87fe4dbd3 100644
--- a/test/EFCore.Tests/ModelBuilding/ModelBuilderNonGenericTest.cs
+++ b/test/EFCore.Tests/ModelBuilding/ModelBuilderNonGenericTest.cs
@@ -9,6 +9,11 @@ public class ModelBuilderNonGenericTest : ModelBuilderTest
{
public class NonGenericNonRelationship : NonRelationshipTestBase
{
+ public NonGenericNonRelationship(ModelBuilderFixtureBase fixture)
+ : base(fixture)
+ {
+ }
+
protected override TestModelBuilder CreateTestModelBuilder(
TestHelpers testHelpers,
Action? configure)
@@ -17,6 +22,11 @@ protected override TestModelBuilder CreateTestModelBuilder(
public class NonGenericComplexType : ComplexTypeTestBase
{
+ public NonGenericComplexType(ModelBuilderFixtureBase fixture)
+ : base(fixture)
+ {
+ }
+
protected override TestModelBuilder CreateTestModelBuilder(
TestHelpers testHelpers,
Action? configure)
@@ -25,6 +35,11 @@ protected override TestModelBuilder CreateTestModelBuilder(
public class NonGenericInheritance : InheritanceTestBase
{
+ public NonGenericInheritance(ModelBuilderFixtureBase fixture)
+ : base(fixture)
+ {
+ }
+
protected override TestModelBuilder CreateTestModelBuilder(
TestHelpers testHelpers,
Action? configure)
@@ -33,6 +48,11 @@ protected override TestModelBuilder CreateTestModelBuilder(
public class NonGenericOwnedTypes : OwnedTypesTestBase
{
+ public NonGenericOwnedTypes(ModelBuilderFixtureBase fixture)
+ : base(fixture)
+ {
+ }
+
[ConditionalFact]
public virtual void OwnsOne_HasOne_with_just_string_navigation_for_non_CLR_property_throws()
{
@@ -55,6 +75,11 @@ protected override TestModelBuilder CreateTestModelBuilder(
public class NonGenericOneToMany : OneToManyTestBase
{
+ public NonGenericOneToMany(ModelBuilderFixtureBase fixture)
+ : base(fixture)
+ {
+ }
+
[ConditionalFact]
public virtual void HasOne_with_just_string_navigation_for_non_CLR_property_throws()
{
@@ -140,6 +165,11 @@ protected override TestModelBuilder CreateTestModelBuilder(
public class NonGenericManyToOne : ManyToOneTestBase
{
+ public NonGenericManyToOne(ModelBuilderFixtureBase fixture)
+ : base(fixture)
+ {
+ }
+
protected override TestModelBuilder CreateTestModelBuilder(
TestHelpers testHelpers,
Action? configure)
@@ -148,6 +178,10 @@ protected override TestModelBuilder CreateTestModelBuilder(
public class NonGenericManyToMany : ManyToManyTestBase
{
+ public NonGenericManyToMany(ModelBuilderFixtureBase fixture)
+ : base(fixture)
+ {
+ }
protected override TestModelBuilder CreateTestModelBuilder(
TestHelpers testHelpers,
Action? configure)
@@ -156,6 +190,11 @@ protected override TestModelBuilder CreateTestModelBuilder(
public class NonGenericOneToOne : OneToOneTestBase
{
+ public NonGenericOneToOne(ModelBuilderFixtureBase fixture)
+ : base(fixture)
+ {
+ }
+
protected override TestModelBuilder CreateTestModelBuilder(
TestHelpers testHelpers,
Action? configure)
diff --git a/test/EFCore.Tests/ModelBuilding/ModelBuilderNonGenericUnqualifiedStringTest.cs b/test/EFCore.Tests/ModelBuilding/ModelBuilderNonGenericUnqualifiedStringTest.cs
index edd5889b72a..9d4b2af94d0 100644
--- a/test/EFCore.Tests/ModelBuilding/ModelBuilderNonGenericUnqualifiedStringTest.cs
+++ b/test/EFCore.Tests/ModelBuilding/ModelBuilderNonGenericUnqualifiedStringTest.cs
@@ -9,6 +9,11 @@ public class ModelBuilderNonGenericUnqualifiedStringTest : ModelBuilderNonGeneri
{
public class NonGenericStringOneToOneType : OneToOneTestBase
{
+ public NonGenericStringOneToOneType(ModelBuilderFixtureBase fixture)
+ : base(fixture)
+ {
+ }
+
protected override TestModelBuilder CreateTestModelBuilder(
TestHelpers testHelpers,
Action? configure)
diff --git a/test/EFCore.Tests/ModelBuilding/ModelBuilderTestBase.cs b/test/EFCore.Tests/ModelBuilding/ModelBuilderTestBase.cs
index a2f9f351722..5d282fc6777 100644
--- a/test/EFCore.Tests/ModelBuilding/ModelBuilderTestBase.cs
+++ b/test/EFCore.Tests/ModelBuilding/ModelBuilderTestBase.cs
@@ -4,88 +4,44 @@
#nullable enable
using Microsoft.EntityFrameworkCore.Diagnostics.Internal;
+using Microsoft.EntityFrameworkCore.Metadata.Internal;
// ReSharper disable InconsistentNaming
namespace Microsoft.EntityFrameworkCore.ModelBuilding;
public abstract partial class ModelBuilderTest
{
- public static void AssertEqual(
- IEnumerable expectedNames,
- IEnumerable actualNames,
- StringComparer? stringComparer = null)
+ public abstract class ModelBuilderTestBase : IClassFixture
{
- stringComparer ??= StringComparer.Ordinal;
- Assert.Equal(
- new SortedSet(expectedNames, stringComparer),
- new SortedSet(actualNames, stringComparer),
- stringComparer);
- }
+ protected ModelBuilderTestBase(ModelBuilderFixtureBase fixture)
+ {
+ Fixture = fixture;
+ }
- public static void AssertEqual(
- IEnumerable expectedProperties,
- IEnumerable actualProperties,
- PropertyComparer? propertyComparer = null)
- {
- propertyComparer ??= new PropertyComparer(compareAnnotations: false);
- Assert.Equal(
- new SortedSet(expectedProperties, propertyComparer),
- new SortedSet(actualProperties, propertyComparer),
- propertyComparer);
- }
+ protected virtual ModelBuilderFixtureBase Fixture { get; }
- public static void AssertEqual(
- IEnumerable expectedNavigations,
- IEnumerable actualNavigations,
- NavigationComparer? navigationComparer = null)
- {
- navigationComparer ??= new NavigationComparer(compareAnnotations: false);
- Assert.Equal(
- new SortedSet(expectedNavigations, navigationComparer),
- new SortedSet(actualNavigations, navigationComparer),
- navigationComparer);
- }
+ protected virtual TestModelBuilder CreateModelBuilder(Action? configure = null)
+ => CreateTestModelBuilder(InMemoryTestHelpers.Instance, configure);
- public static void AssertEqual(
- IEnumerable expectedKeys,
- IEnumerable actualKeys,
- TestKeyComparer? testKeyComparer = null)
- {
- testKeyComparer ??= new TestKeyComparer(compareAnnotations: false);
- Assert.Equal(
- new SortedSet(expectedKeys, testKeyComparer),
- new SortedSet(actualKeys, testKeyComparer),
- testKeyComparer);
- }
+ protected abstract TestModelBuilder CreateTestModelBuilder(
+ TestHelpers testHelpers,
+ Action? configure = null);
- public static void AssertEqual(
- IEnumerable expectedForeignKeys,
- IEnumerable actualForeignKeys,
- ForeignKeyStrictComparer? foreignKeyComparer = null)
- {
- foreignKeyComparer ??= new ForeignKeyStrictComparer(compareAnnotations: false);
- Assert.Equal(
- new SortedSet(expectedForeignKeys, foreignKeyComparer),
- new SortedSet(actualForeignKeys, foreignKeyComparer),
- foreignKeyComparer);
- }
+ public virtual void AssertEqual(
+ IReadOnlyModel expected,
+ IReadOnlyModel actual,
+ bool compareAnnotations = false)
+ => Fixture.AssertEqual(expected, actual, compareAnnotations);
- public static void AssertEqual(
- IEnumerable expectedIndexes,
- IEnumerable actualIndexes,
- TestIndexComparer? testIndexComparer = null)
- {
- testIndexComparer ??= new TestIndexComparer(compareAnnotations: false);
- Assert.Equal(
- new SortedSet(expectedIndexes, testIndexComparer),
- new SortedSet(actualIndexes, testIndexComparer),
- testIndexComparer);
- }
+ public virtual void AssertEqual(
+ IEnumerable expectedProperties,
+ IEnumerable actualProperties,
+ bool assertOrder = false,
+ bool compareAnnotations = false)
+ => Fixture.AssertEqual(expectedProperties, actualProperties, assertOrder, compareAnnotations);
- public abstract class ModelBuilderTestBase
- {
- protected virtual TestModelBuilder CreateModelBuilder(Action? configure = null)
- => CreateTestModelBuilder(InMemoryTestHelpers.Instance, configure);
+ public virtual IReadOnlyModel Clone(IReadOnlyModel model)
+ => Fixture.Clone(model);
protected TestModelBuilder HobNobBuilder()
{
@@ -96,10 +52,1012 @@ protected TestModelBuilder HobNobBuilder()
return builder;
}
+ }
- protected abstract TestModelBuilder CreateTestModelBuilder(
- TestHelpers testHelpers,
- Action? configure = null);
+ public class ModelBuilderFixtureBase
+ {
+ public virtual void AssertEqual(
+ IReadOnlyModel expected,
+ IReadOnlyModel actual,
+ bool compareAnnotations = false)
+ => AssertEqual(
+ expected,
+ actual,
+ compareAnnotations ? expected.GetAnnotations() : Enumerable.Empty(),
+ compareAnnotations ? actual.GetAnnotations() : Enumerable.Empty(),
+ compareMemberAnnotations: compareAnnotations);
+
+ public virtual bool AssertEqual(IReadOnlyModel expected, IReadOnlyModel actual,
+ IEnumerable expectedAnnotations, IEnumerable actualAnnotations,
+ bool compareMemberAnnotations = false)
+ {
+ expectedAnnotations = expectedAnnotations.Where(a => !CoreAnnotationNames.AllNames.Contains(a.Name));
+ actualAnnotations = actualAnnotations.Where(a => !CoreAnnotationNames.AllNames.Contains(a.Name));
+
+ Assert.Multiple(
+ () => Assert.Equal(expected.ModelId, actual.ModelId),
+ () => Assert.Equal(expected.GetProductVersion(), actual.GetProductVersion()),
+ () => Assert.Equal(expected.GetPropertyAccessMode(), actual.GetPropertyAccessMode()),
+ () => Assert.Equal(expected.GetChangeTrackingStrategy(), actual.GetChangeTrackingStrategy()),
+ () => AssertEqual(expected.GetEntityTypes(), actual.GetEntityTypes(),
+ assertOrder: true, compareAnnotations: compareMemberAnnotations),
+ () => Assert.Equal(expectedAnnotations, actualAnnotations, TestAnnotationComparer.Instance));
+
+ return true;
+ }
+
+ public virtual void AssertEqual(
+ IEnumerable expectedEntityTypes,
+ IEnumerable actualEntityTypes,
+ bool assertOrder = false,
+ bool compareAnnotations = false)
+ {
+ if (!assertOrder)
+ {
+ expectedEntityTypes = expectedEntityTypes.OrderBy(p => p.Name);
+ actualEntityTypes = actualEntityTypes.OrderBy(p => p.Name);
+ }
+
+ Assert.Equal(expectedEntityTypes, actualEntityTypes,
+ (expected, actual) =>
+ AssertEqual(
+ expected,
+ actual,
+ compareAnnotations ? expected.GetAnnotations() : Enumerable.Empty(),
+ compareAnnotations ? actual.GetAnnotations() : Enumerable.Empty(),
+ compareBackreferences: false,
+ compareMemberAnnotations: compareAnnotations));
+ }
+
+ public virtual bool AssertEqual(IReadOnlyEntityType? expected, IReadOnlyEntityType? actual,
+ IEnumerable expectedAnnotations, IEnumerable actualAnnotations,
+ bool compareBackreferences = false, bool compareMemberAnnotations = false)
+ {
+ if (expected == null)
+ {
+ Assert.Null(actual);
+
+ return true;
+ }
+
+ Assert.NotNull(actual);
+
+ expectedAnnotations = expectedAnnotations.Where(a => !CoreAnnotationNames.AllNames.Contains(a.Name));
+ actualAnnotations = actualAnnotations.Where(a => !CoreAnnotationNames.AllNames.Contains(a.Name));
+
+ Assert.Multiple(
+ () => Assert.Equal(expected.Name, actual.Name),
+ () => Assert.Equal(expected.ClrType, actual.ClrType),
+ () => Assert.Equal(expected.HasSharedClrType, actual.HasSharedClrType),
+ () => Assert.Equal(expected.IsPropertyBag, actual.IsPropertyBag),
+ () => Assert.Equal(expected.GetQueryFilter(), actual.GetQueryFilter()),
+ () => Assert.Equal(expected.GetSeedData(), actual.GetSeedData()),
+ () => Assert.Equal(expected.GetPropertyAccessMode(), actual.GetPropertyAccessMode()),
+ () => Assert.Equal(expected.GetChangeTrackingStrategy(), actual.GetChangeTrackingStrategy()),
+ () => Assert.Equal(expected.GetDiscriminatorPropertyName(), actual.GetDiscriminatorPropertyName()),
+ () => Assert.Equal(expected.GetDiscriminatorValue(), actual.GetDiscriminatorValue()),
+ () => Assert.Equal(expected.GetIsDiscriminatorMappingComplete(), actual.GetIsDiscriminatorMappingComplete()),
+ () => AssertEqual(expected.GetProperties(), actual.GetProperties(),
+ assertOrder: true, compareAnnotations: compareMemberAnnotations),
+ () => AssertEqual(expected.GetServiceProperties(), actual.GetServiceProperties(),
+ assertOrder: true, compareAnnotations: compareMemberAnnotations),
+ () => AssertEqual(expected.GetSkipNavigations(), actual.GetSkipNavigations(),
+ assertOrder: true, compareAnnotations: compareMemberAnnotations),
+ () => AssertEqual(expected.GetForeignKeys(), actual.GetForeignKeys(),
+ assertOrder: true, compareAnnotations: compareMemberAnnotations),
+ () => AssertEqual(expected.GetKeys(), actual.GetKeys(),
+ assertOrder: true, compareAnnotations: compareMemberAnnotations),
+ () => AssertEqual(expected.GetIndexes(), actual.GetIndexes(),
+ assertOrder: true, compareAnnotations: compareMemberAnnotations),
+ () => AssertEqual(expected.GetComplexProperties(), actual.GetComplexProperties(),
+ assertOrder: true, compareAnnotations: compareMemberAnnotations),
+ () =>
+ {
+ if (compareBackreferences)
+ {
+ Assert.Equal(expected.BaseType?.Name, actual.BaseType?.Name);
+ }
+ },
+ () =>
+ {
+ if (compareBackreferences)
+ {
+ Assert.Equal(expected.GetReferencingForeignKeys(), actual.GetReferencingForeignKeys());
+ }
+ },
+ () => Assert.Equal(expectedAnnotations, actualAnnotations, TestAnnotationComparer.Instance));
+
+ return true;
+ }
+
+ public virtual bool AssertEqual(IReadOnlyComplexType expected, IReadOnlyComplexType actual,
+ IEnumerable expectedAnnotations, IEnumerable actualAnnotations,
+ bool compareBackreferences = false,
+ bool compareMemberAnnotations = false)
+ {
+ expectedAnnotations = expectedAnnotations.Where(a => !CoreAnnotationNames.AllNames.Contains(a.Name));
+ actualAnnotations = actualAnnotations.Where(a => !CoreAnnotationNames.AllNames.Contains(a.Name));
+
+ Assert.Multiple(
+ () => Assert.Equal(expected.Name, actual.Name),
+ () => Assert.Equal(expected.ClrType, actual.ClrType),
+ () => Assert.Equal(expected.GetPropertyAccessMode(), actual.GetPropertyAccessMode()),
+ () => Assert.Equal(expected.GetChangeTrackingStrategy(), actual.GetChangeTrackingStrategy()),
+ () => AssertEqual(expected.GetProperties(), actual.GetProperties(),
+ assertOrder: true, compareAnnotations: compareMemberAnnotations),
+ () => AssertEqual(expected.GetComplexProperties(), actual.GetComplexProperties(),
+ assertOrder: true, compareAnnotations: compareMemberAnnotations),
+ () =>
+ {
+ if (compareBackreferences)
+ {
+ Assert.Equal(expected.ContainingEntityType.Name, actual.ContainingEntityType.Name);
+ }
+ },
+ () => Assert.Equal(expectedAnnotations, actualAnnotations, TestAnnotationComparer.Instance));
+
+ return true;
+ }
+
+ public virtual void AssertEqual(
+ IEnumerable expectedProperties,
+ IEnumerable actualProperties,
+ bool assertOrder = false,
+ bool compareAnnotations = false)
+ {
+ if (!assertOrder)
+ {
+ expectedProperties = expectedProperties.OrderBy(p => p.Name);
+ actualProperties = actualProperties.OrderBy(p => p.Name);
+ }
+
+ Assert.Equal(expectedProperties, actualProperties,
+ (expected, actual) =>
+ AssertEqual(
+ expected,
+ actual,
+ compareAnnotations ? expected.GetAnnotations() : Enumerable.Empty(),
+ compareAnnotations ? actual.GetAnnotations() : Enumerable.Empty(),
+ compareBackreferences: false,
+ compareMemberAnnotations: compareAnnotations));
+ }
+
+ public virtual bool AssertEqual(IReadOnlyComplexProperty? expected, IReadOnlyComplexProperty? actual,
+ IEnumerable expectedAnnotations, IEnumerable actualAnnotations,
+ bool compareBackreferences = false,
+ bool compareMemberAnnotations = false)
+ {
+ if (expected == null)
+ {
+ Assert.Null(actual);
+
+ return true;
+ }
+
+ Assert.NotNull(actual);
+
+ expectedAnnotations = expectedAnnotations.Where(a => !CoreAnnotationNames.AllNames.Contains(a.Name));
+ actualAnnotations = actualAnnotations.Where(a => !CoreAnnotationNames.AllNames.Contains(a.Name));
+
+ Assert.Multiple(
+ () => Assert.Equal(expected.Name, actual.Name),
+ () => Assert.Equal(expected.ClrType, actual.ClrType),
+ () => Assert.Equal(expected.FieldInfo, actual.FieldInfo),
+ () => Assert.Equal(expected.GetIdentifyingMemberInfo(), actual.GetIdentifyingMemberInfo()),
+ () => Assert.Equal(expected.IsShadowProperty(), actual.IsShadowProperty()),
+ () => Assert.Equal(expected.IsNullable, actual.IsNullable),
+ () => Assert.Equal(expected.Sentinel, actual.Sentinel),
+ () => Assert.Equal(expected.GetPropertyAccessMode(), actual.GetPropertyAccessMode()),
+ () => AssertEqual(expected.ComplexType, actual.ComplexType,
+ compareMemberAnnotations ? expected.GetAnnotations() : Enumerable.Empty(),
+ compareMemberAnnotations ? actual.GetAnnotations() : Enumerable.Empty(),
+ compareBackreferences: false,
+ compareMemberAnnotations: compareMemberAnnotations),
+ () =>
+ {
+ if (compareBackreferences)
+ {
+ Assert.Equal(expected.DeclaringType.Name, actual.DeclaringType.Name);
+ }
+ },
+ () => Assert.Equal(expectedAnnotations, actualAnnotations, TestAnnotationComparer.Instance));
+
+ return true;
+ }
+
+ public virtual void AssertEqual(
+ IEnumerable expectedProperties,
+ IEnumerable actualProperties,
+ bool assertOrder = false,
+ bool compareAnnotations = false)
+ {
+ if (!assertOrder)
+ {
+ expectedProperties = expectedProperties.OrderBy(p => p.Name);
+ actualProperties = actualProperties.OrderBy(p => p.Name);
+ }
+
+ Assert.Equal(expectedProperties, actualProperties,
+ (expected, actual) =>
+ AssertEqual(
+ expected,
+ actual,
+ compareAnnotations ? expected.GetAnnotations() : Enumerable.Empty(),
+ compareAnnotations ? actual.GetAnnotations() : Enumerable.Empty(),
+ compareBackreferences: false));
+ }
+
+ public virtual bool AssertEqual(IReadOnlyProperty? expected, IReadOnlyProperty? actual,
+ IEnumerable expectedAnnotations, IEnumerable actualAnnotations,
+ bool compareBackreferences = false)
+ {
+ if (expected == null)
+ {
+ Assert.Null(actual);
+
+ return true;
+ }
+
+ Assert.NotNull(actual);
+
+ expectedAnnotations = expectedAnnotations.Where(a => !CoreAnnotationNames.AllNames.Contains(a.Name));
+ actualAnnotations = actualAnnotations.Where(a => !CoreAnnotationNames.AllNames.Contains(a.Name));
+
+ Assert.Multiple(
+ () => Assert.Equal(expected.Name, actual.Name),
+ () => Assert.Equal(expected.ClrType, actual.ClrType),
+ () => Assert.Equal(expected.FieldInfo?.Name, actual.FieldInfo?.Name),
+ () => Assert.Equal(expected.GetIdentifyingMemberInfo()?.Name, actual.GetIdentifyingMemberInfo()?.Name),
+ () => Assert.Equal(expected.IsShadowProperty(), actual.IsShadowProperty()),
+ () => Assert.Equal(expected.IsNullable, actual.IsNullable),
+ () => Assert.Equal(expected.IsConcurrencyToken, actual.IsConcurrencyToken),
+ () => Assert.Equal(expected.Sentinel, actual.Sentinel),
+ () => Assert.Equal(expected.ValueGenerated, actual.ValueGenerated),
+ () => Assert.Equal(expected.GetPropertyAccessMode(), actual.GetPropertyAccessMode()),
+ () => Assert.Equal(expected.GetBeforeSaveBehavior(), actual.GetBeforeSaveBehavior()),
+ () => Assert.Equal(expected.GetAfterSaveBehavior(), actual.GetAfterSaveBehavior()),
+ () => Assert.Equal(expected.GetMaxLength(), actual.GetMaxLength()),
+ () => Assert.Equal(expected.GetPrecision(), actual.GetPrecision()),
+ () => Assert.Equal(expected.GetScale(), actual.GetScale()),
+ () => Assert.Equal(expected.IsUnicode(), actual.IsUnicode()),
+ () => Assert.Equal(expected.GetProviderClrType(), actual.GetProviderClrType()),
+ () => Assert.Equal(expected.GetValueConverter()?.GetType(), actual.GetValueConverter()?.GetType()),
+ () => Assert.Equal(expected.IsKey(), actual.IsKey()),
+ () => Assert.Equal(expected.IsForeignKey(), actual.IsForeignKey()),
+ () => Assert.Equal(expected.IsIndex(), actual.IsIndex()),
+ () =>
+ {
+ if (compareBackreferences)
+ {
+ Assert.Equal(expected.DeclaringType.Name, actual.DeclaringType.Name);
+ }
+ },
+ () =>
+ {
+ if (compareBackreferences)
+ {
+ Assert.Equal(expected.GetContainingForeignKeys(), actual.GetContainingForeignKeys(), ForeignKeyComparer.Instance);
+ }
+ },
+ () =>
+ {
+ if (compareBackreferences)
+ {
+ Assert.Equal(expected.GetContainingIndexes(), actual.GetContainingIndexes(), IndexComparer.Instance);
+ }
+ },
+ () =>
+ {
+ if (compareBackreferences)
+ {
+ Assert.Equal(expected.GetContainingKeys(), actual.GetContainingKeys(), KeyComparer.Instance);
+ }
+ },
+ () => Assert.Equal(expectedAnnotations, actualAnnotations, TestAnnotationComparer.Instance));
+
+ return true;
+ }
+
+ public virtual void AssertEqual(
+ IEnumerable expectedProperties,
+ IEnumerable actualProperties,
+ bool assertOrder = false,
+ bool compareAnnotations = false)
+ {
+ if (!assertOrder)
+ {
+ expectedProperties = expectedProperties.OrderBy(p => p.Name);
+ actualProperties = actualProperties.OrderBy(p => p.Name);
+ }
+
+ Assert.Equal(expectedProperties, actualProperties,
+ (expected, actual) =>
+ AssertEqual(
+ expected,
+ actual,
+ compareAnnotations ? expected.GetAnnotations() : Enumerable.Empty(),
+ compareAnnotations ? actual.GetAnnotations() : Enumerable.Empty(),
+ compareBackreferences: false));
+ }
+
+ public virtual bool AssertEqual(IReadOnlyServiceProperty? expected, IReadOnlyServiceProperty? actual,
+ IEnumerable expectedAnnotations, IEnumerable actualAnnotations,
+ bool compareBackreferences = false)
+ {
+ if (expected == null)
+ {
+ Assert.Null(actual);
+
+ return true;
+ }
+
+ Assert.NotNull(actual);
+
+ expectedAnnotations = expectedAnnotations.Where(a => !CoreAnnotationNames.AllNames.Contains(a.Name));
+ actualAnnotations = actualAnnotations.Where(a => !CoreAnnotationNames.AllNames.Contains(a.Name));
+
+ Assert.Multiple(
+ () => Assert.Equal(expected.Name, actual.Name),
+ () => Assert.Equal(expected.ClrType, actual.ClrType),
+ () => Assert.Equal(expected.FieldInfo, actual.FieldInfo),
+ () => Assert.Equal(expected.GetIdentifyingMemberInfo(), actual.GetIdentifyingMemberInfo()),
+ () => Assert.Equal(expected.IsShadowProperty(), actual.IsShadowProperty()),
+ () => Assert.Equal(expected.Sentinel, actual.Sentinel),
+ () => Assert.Equal(expected.GetPropertyAccessMode(), actual.GetPropertyAccessMode()),
+ () =>
+ {
+ if (compareBackreferences)
+ {
+ Assert.Equal(expected.DeclaringType.Name, actual.DeclaringType.Name);
+ }
+ },
+ () => Assert.Equal(expectedAnnotations, actualAnnotations, TestAnnotationComparer.Instance));
+
+ return true;
+ }
+
+ public virtual void AssertEqual(
+ IEnumerable expectedNavigations,
+ IEnumerable actualNavigations,
+ bool assertOrder = false,
+ bool compareAnnotations = false)
+ {
+ if (!assertOrder)
+ {
+ expectedNavigations = expectedNavigations.OrderBy(p => p.Name);
+ actualNavigations = actualNavigations.OrderBy(p => p.Name);
+ }
+
+ Assert.Equal(expectedNavigations, actualNavigations,
+ (expected, actual) =>
+ AssertEqual(
+ expected,
+ actual,
+ compareAnnotations ? expected.GetAnnotations() : Enumerable.Empty(),
+ compareAnnotations ? actual.GetAnnotations() : Enumerable.Empty(),
+ compareBackreferences: false));
+ }
+
+ public virtual bool AssertEqual(IReadOnlyNavigation? expected, IReadOnlyNavigation? actual,
+ IEnumerable expectedAnnotations, IEnumerable actualAnnotations,
+ bool compareBackreferences = false)
+ {
+ if (expected == null)
+ {
+ Assert.Null(actual);
+
+ return true;
+ }
+
+ Assert.NotNull(actual);
+
+ expectedAnnotations = expectedAnnotations.Where(a => !CoreAnnotationNames.AllNames.Contains(a.Name));
+ actualAnnotations = actualAnnotations.Where(a => !CoreAnnotationNames.AllNames.Contains(a.Name));
+
+ Assert.Multiple(
+ () => Assert.Equal(expected.Name, actual.Name),
+ () => Assert.Equal(expected.ClrType, actual.ClrType),
+ () => Assert.Equal(expected.FieldInfo, actual.FieldInfo),
+ () => Assert.Equal(expected.GetIdentifyingMemberInfo(), actual.GetIdentifyingMemberInfo()),
+ () => Assert.Equal(expected.IsShadowProperty(), actual.IsShadowProperty()),
+ () => Assert.Equal(expected.IsCollection, actual.IsCollection),
+ () => Assert.Equal(expected.IsEagerLoaded, actual.IsEagerLoaded),
+ () => Assert.Equal(expected.LazyLoadingEnabled, actual.LazyLoadingEnabled),
+ () => Assert.Equal(expected.Sentinel, actual.Sentinel),
+ () => Assert.Equal(expected.GetPropertyAccessMode(), actual.GetPropertyAccessMode()),
+ () =>
+ {
+ if (compareBackreferences)
+ {
+ Assert.Equal(expected.DeclaringType.Name, actual.DeclaringType.Name);
+ }
+ },
+ () =>
+ {
+ if (compareBackreferences)
+ {
+ Assert.Equal(expected.ForeignKey, actual.ForeignKey, ForeignKeyComparer.Instance);
+ }
+ },
+ () =>
+ {
+ if (compareBackreferences)
+ {
+ Assert.Equal(expected.Inverse?.Name, actual.Inverse?.Name);
+ }
+ },
+ () => Assert.Equal(expectedAnnotations, actualAnnotations, TestAnnotationComparer.Instance));
+
+ return true;
+ }
+
+ public virtual void AssertEqual(
+ IEnumerable expectedNavigations,
+ IEnumerable actualNavigations,
+ bool assertOrder = false,
+ bool compareAnnotations = false)
+ {
+ if (!assertOrder)
+ {
+ expectedNavigations = expectedNavigations.OrderBy(p => p.Name);
+ actualNavigations = actualNavigations.OrderBy(p => p.Name);
+ }
+
+ Assert.Equal(expectedNavigations, actualNavigations,
+ (expected, actual) =>
+ AssertEqual(
+ expected,
+ actual,
+ compareAnnotations ? expected.GetAnnotations() : Enumerable.Empty(),
+ compareAnnotations ? actual.GetAnnotations() : Enumerable.Empty(),
+ compareBackreferences: false));
+ }
+
+ public virtual bool AssertEqual(IReadOnlySkipNavigation expected, IReadOnlySkipNavigation actual,
+ IEnumerable expectedAnnotations, IEnumerable actualAnnotations,
+ bool compareBackreferences = false)
+ {
+ if (expected == null)
+ {
+ Assert.Null(actual);
+
+ return true;
+ }
+
+ Assert.NotNull(actual);
+
+ expectedAnnotations = expectedAnnotations.Where(a => !CoreAnnotationNames.AllNames.Contains(a.Name));
+ actualAnnotations = actualAnnotations.Where(a => !CoreAnnotationNames.AllNames.Contains(a.Name));
+
+ Assert.Multiple(
+ () => Assert.Equal(expected.Name, actual.Name),
+ () => Assert.Equal(expected.ClrType, actual.ClrType),
+ () => Assert.Equal(expected.FieldInfo, actual.FieldInfo),
+ () => Assert.Equal(expected.GetIdentifyingMemberInfo(), actual.GetIdentifyingMemberInfo()),
+ () => Assert.Equal(expected.IsShadowProperty(), actual.IsShadowProperty()),
+ () => Assert.Equal(expected.IsCollection, actual.IsCollection),
+ () => Assert.Equal(expected.IsEagerLoaded, actual.IsEagerLoaded),
+ () => Assert.Equal(expected.LazyLoadingEnabled, actual.LazyLoadingEnabled),
+ () => Assert.Equal(expected.Sentinel, actual.Sentinel),
+ () => Assert.Equal(expected.GetPropertyAccessMode(), actual.GetPropertyAccessMode()),
+ () =>
+ {
+ if (compareBackreferences)
+ {
+ Assert.Equal(expected.DeclaringType.Name, actual.DeclaringType.Name);
+ }
+ },
+ () =>
+ {
+ if (compareBackreferences)
+ {
+ Assert.Equal(expected.ForeignKey!, actual.ForeignKey!, ForeignKeyComparer.Instance);
+ }
+ },
+ () =>
+ {
+ if (compareBackreferences)
+ {
+ Assert.Equal(expected.Inverse?.Name, actual.Inverse?.Name);
+ }
+ },
+ () => Assert.Equal(expectedAnnotations, actualAnnotations, TestAnnotationComparer.Instance));
+
+ return true;
+ }
+
+ public virtual void AssertEqual(
+ IEnumerable expectedKeys,
+ IEnumerable actualKeys,
+ bool assertOrder = false,
+ bool compareAnnotations = false)
+ {
+ if (!assertOrder)
+ {
+ expectedKeys = expectedKeys.Order(KeyComparer.Instance);
+ actualKeys = actualKeys.Order(KeyComparer.Instance);
+ }
+
+ Assert.Equal(expectedKeys, actualKeys,
+ (expected, actual) =>
+ AssertEqual(
+ expected,
+ actual,
+ compareAnnotations ? expected.GetAnnotations() : Enumerable.Empty(),
+ compareAnnotations ? actual.GetAnnotations() : Enumerable.Empty(),
+ compareBackreferences: false));
+ }
+
+ public virtual bool AssertEqual(IReadOnlyKey expected, IReadOnlyKey actual,
+ IEnumerable expectedAnnotations, IEnumerable actualAnnotations,
+ bool compareBackreferences = false)
+ {
+ if (expected == null)
+ {
+ Assert.Null(actual);
+
+ return true;
+ }
+
+ Assert.NotNull(actual);
+
+ expectedAnnotations = expectedAnnotations.Where(a => !CoreAnnotationNames.AllNames.Contains(a.Name));
+ actualAnnotations = actualAnnotations.Where(a => !CoreAnnotationNames.AllNames.Contains(a.Name));
+
+ Assert.Multiple(
+ () =>
+ {
+ if (compareBackreferences)
+ {
+ Assert.Equal(expected, actual, KeyComparer.Instance);
+ }
+ else
+ {
+ Assert.Equal(expected.Properties, actual.Properties, PropertyListComparer.Instance);
+ }
+ },
+ () => Assert.Equal(expected.IsPrimaryKey(), actual.IsPrimaryKey()),
+ () =>
+ {
+ if (compareBackreferences)
+ {
+ Assert.Equal(expected.DeclaringEntityType.Name, actual.DeclaringEntityType.Name);
+ }
+ },
+ () => Assert.Equal(expectedAnnotations, actualAnnotations, TestAnnotationComparer.Instance));
+
+ return true;
+ }
+
+ public virtual void AssertEqual(
+ IEnumerable expectedForeignKey,
+ IEnumerable actualForeignKey,
+ bool assertOrder = false,
+ bool compareAnnotations = false)
+ {
+ if (!assertOrder)
+ {
+ expectedForeignKey = expectedForeignKey.Order(ForeignKeyComparer.Instance);
+ actualForeignKey = actualForeignKey.Order(ForeignKeyComparer.Instance);
+ }
+
+ Assert.Equal(expectedForeignKey, actualForeignKey,
+ (expected, actual) =>
+ AssertEqual(
+ expected,
+ actual,
+ compareAnnotations ? expected.GetAnnotations() : Enumerable.Empty(),
+ compareAnnotations ? actual.GetAnnotations() : Enumerable.Empty(),
+ compareBackreferences: false,
+ compareMemberAnnotations: compareAnnotations));
+ }
+
+ public virtual bool AssertEqual(IReadOnlyForeignKey expected, IReadOnlyForeignKey actual,
+ IEnumerable expectedAnnotations, IEnumerable actualAnnotations,
+ bool compareBackreferences = false,
+ bool compareMemberAnnotations = false)
+ {
+ if (expected == null)
+ {
+ Assert.Null(actual);
+
+ return true;
+ }
+
+ Assert.NotNull(actual);
+
+ expectedAnnotations = expectedAnnotations.Where(a => !CoreAnnotationNames.AllNames.Contains(a.Name));
+ actualAnnotations = actualAnnotations.Where(a => !CoreAnnotationNames.AllNames.Contains(a.Name));
+
+ Assert.Multiple(
+ () =>
+ {
+ if (compareBackreferences)
+ {
+ Assert.Equal(expected, actual, ForeignKeyComparer.Instance);
+ }
+ else
+ {
+ Assert.Equal(expected.Properties, actual.Properties, PropertyListComparer.Instance);
+ Assert.Equal(expected.PrincipalKey.Properties, actual.PrincipalKey.Properties, PropertyListComparer.Instance);
+ }
+ },
+ () => Assert.Equal(expected.IsRequired, actual.IsRequired),
+ () => Assert.Equal(expected.IsRequiredDependent, actual.IsRequiredDependent),
+ () => Assert.Equal(expected.IsUnique, actual.IsUnique),
+ () => Assert.Equal(expected.DeleteBehavior, actual.DeleteBehavior),
+ () => AssertEqual(expected.DependentToPrincipal, actual.DependentToPrincipal,
+ compareMemberAnnotations
+ ? expected.DependentToPrincipal?.GetAnnotations() ?? Enumerable.Empty()
+ : Enumerable.Empty(),
+ compareMemberAnnotations
+ ? actual.DependentToPrincipal?.GetAnnotations() ?? Enumerable.Empty()
+ : Enumerable.Empty(),
+ compareBackreferences: true),
+ () => AssertEqual(expected.PrincipalToDependent, actual.PrincipalToDependent,
+ compareMemberAnnotations
+ ? expected.PrincipalToDependent?.GetAnnotations() ?? Enumerable.Empty()
+ : Enumerable.Empty(),
+ compareMemberAnnotations
+ ? actual.PrincipalToDependent?.GetAnnotations() ?? Enumerable.Empty()
+ : Enumerable.Empty(),
+ compareBackreferences: true),
+ () =>
+ {
+ if (compareBackreferences)
+ {
+ Assert.Equal(expected.DeclaringEntityType.Name, actual.DeclaringEntityType.Name);
+ }
+ },
+ () => Assert.Equal(expectedAnnotations, actualAnnotations, TestAnnotationComparer.Instance));
+
+ return true;
+ }
+
+ public virtual void AssertEqual(
+ IEnumerable expectedIndex,
+ IEnumerable actualIndex,
+ bool assertOrder = false,
+ bool compareAnnotations = false)
+ {
+ if (!assertOrder)
+ {
+ expectedIndex = expectedIndex.Order(IndexComparer.Instance);
+ actualIndex = actualIndex.Order(IndexComparer.Instance);
+ }
+
+ Assert.Equal(expectedIndex, actualIndex,
+ (expected, actual) =>
+ AssertEqual(
+ expected,
+ actual,
+ compareAnnotations ? expected.GetAnnotations() : Enumerable.Empty(),
+ compareAnnotations ? actual.GetAnnotations() : Enumerable.Empty(),
+ compareBackreferences: false));
+ }
+
+ public virtual bool AssertEqual(IReadOnlyIndex expected, IReadOnlyIndex actual,
+ IEnumerable expectedAnnotations, IEnumerable actualAnnotations,
+ bool compareBackreferences = false)
+ {
+ if (expected == null)
+ {
+ Assert.Null(actual);
+
+ return true;
+ }
+
+ Assert.NotNull(actual);
+
+ expectedAnnotations = expectedAnnotations.Where(a => !CoreAnnotationNames.AllNames.Contains(a.Name));
+ actualAnnotations = actualAnnotations.Where(a => !CoreAnnotationNames.AllNames.Contains(a.Name));
+
+ Assert.Multiple(
+ () =>
+ {
+ if (compareBackreferences)
+ {
+ Assert.Equal(expected, actual, IndexComparer.Instance);
+ }
+ else
+ {
+ Assert.Equal(expected.Properties, actual.Properties, PropertyListComparer.Instance);
+ }
+ },
+ () => Assert.Equal(expected.IsDescending, actual.IsDescending),
+ () => Assert.Equal(expected.IsUnique, actual.IsUnique),
+ () => Assert.Equal(expected.Name, actual.Name),
+ () =>
+ {
+ if (compareBackreferences)
+ {
+ Assert.Equal(expected.DeclaringEntityType.Name, actual.DeclaringEntityType.Name);
+ }
+ },
+ () => Assert.Equal(expectedAnnotations, actualAnnotations, TestAnnotationComparer.Instance));
+
+ return true;
+ }
+
+ public virtual IReadOnlyModel Clone(IReadOnlyModel model)
+ {
+ IMutableModel modelClone = new Model(model.ModelId);
+ modelClone.SetChangeTrackingStrategy(model.GetChangeTrackingStrategy());
+
+ if (model.GetProductVersion() is string productVersion)
+ {
+ modelClone.SetProductVersion(productVersion);
+ }
+
+ modelClone.SetPropertyAccessMode(model.GetPropertyAccessMode());
+ modelClone.AddAnnotations(model.GetAnnotations().Where(a => !CoreAnnotationNames.AllNames.Contains(a.Name)));
+
+ var clonedEntityTypes = new Dictionary();
+ foreach (var entityType in ((IModel)model).GetEntityTypesInHierarchicalOrder())
+ {
+ var clonedEntityType = entityType.HasSharedClrType
+ ? modelClone.AddEntityType(entityType.Name, entityType.ClrType)
+ : modelClone.AddEntityType(entityType.ClrType);
+
+ Copy(entityType, clonedEntityType);
+ clonedEntityTypes.Add(entityType, clonedEntityType);
+ }
+
+ foreach (var clonedEntityType in clonedEntityTypes)
+ {
+ var targetEntityType = clonedEntityType.Value;
+ foreach (var foreignKey in clonedEntityType.Key.GetDeclaredForeignKeys())
+ {
+ var targetPrincipalEntityType = targetEntityType.Model.FindEntityType(foreignKey.PrincipalEntityType.Name)!;
+ var clonedForeignKey = targetEntityType.AddForeignKey(
+ foreignKey.Properties.Select(p => targetEntityType.FindProperty(p.Name)!).ToList(),
+ targetPrincipalEntityType.FindKey(
+ foreignKey.PrincipalKey.Properties.Select(p => targetPrincipalEntityType.FindProperty(p.Name)!).ToList())!,
+ targetPrincipalEntityType);
+ Copy(foreignKey, clonedForeignKey);
+ }
+ }
+
+ foreach (var clonedEntityType in clonedEntityTypes)
+ {
+ foreach (var skipNavigation in clonedEntityType.Key.GetDeclaredSkipNavigations())
+ {
+ var targetEntityType = clonedEntityType.Value;
+ var otherEntityType = targetEntityType.Model.FindEntityType(skipNavigation.TargetEntityType.Name)!;
+ Copy(skipNavigation, clonedEntityType.Value.AddSkipNavigation(
+ skipNavigation.Name,
+ skipNavigation.GetIdentifyingMemberInfo(),
+ otherEntityType,
+ skipNavigation.IsCollection,
+ skipNavigation.IsOnDependent));
+ }
+ }
+
+ return modelClone;
+ }
+
+ protected virtual void Copy(IReadOnlyEntityType sourceEntityType, IMutableEntityType targetEntityType)
+ {
+ if (sourceEntityType.BaseType != null)
+ {
+ targetEntityType.BaseType = targetEntityType.Model.FindEntityType(sourceEntityType.BaseType.Name);
+ }
+
+ targetEntityType.SetQueryFilter(sourceEntityType.GetQueryFilter());
+ targetEntityType.AddData(sourceEntityType.GetSeedData());
+ targetEntityType.SetPropertyAccessMode(sourceEntityType.GetPropertyAccessMode());
+ targetEntityType.SetChangeTrackingStrategy(sourceEntityType.GetChangeTrackingStrategy());
+ targetEntityType.SetDiscriminatorMappingComplete(sourceEntityType.GetIsDiscriminatorMappingComplete());
+ targetEntityType.SetDiscriminatorValue(sourceEntityType.GetDiscriminatorValue());
+
+ foreach (var property in sourceEntityType.GetDeclaredProperties())
+ {
+ var targetProperty = property.IsShadowProperty()
+ ? targetEntityType.AddProperty(property.Name, property.ClrType)
+ : targetEntityType.AddProperty(property.Name, property.ClrType, property.GetIdentifyingMemberInfo()!);
+ Copy(property, targetProperty);
+ }
+
+ if (sourceEntityType.BaseType == null
+ && sourceEntityType.GetDiscriminatorPropertyName() is string discriminatorPropertyName)
+ {
+ targetEntityType.SetDiscriminatorProperty(
+ targetEntityType.FindProperty(discriminatorPropertyName)!);
+ }
+
+ foreach (var property in sourceEntityType.GetDeclaredComplexProperties())
+ {
+ Copy(property, targetEntityType.AddComplexProperty(
+ property.Name,
+ property.ClrType,
+ property.ComplexType.ClrType,
+ property.ComplexType.Name,
+ collection: property.IsCollection));
+ }
+
+ foreach (var property in sourceEntityType.GetDeclaredServiceProperties())
+ {
+ Copy(property, targetEntityType.AddServiceProperty(
+ property.GetIdentifyingMemberInfo()!, property.ClrType));
+ }
+
+ foreach (var key in sourceEntityType.GetDeclaredKeys())
+ {
+ Copy(key, targetEntityType.AddKey(
+ key.Properties.Select(p => targetEntityType.FindProperty(p.Name)!).ToList()));
+ }
+
+ foreach (var index in sourceEntityType.GetDeclaredIndexes())
+ {
+ var targetProperties = index.Properties.Select(p => targetEntityType.FindProperty(p.Name)!).ToList();
+ var clonedIndex = index.Name == null
+ ? targetEntityType.AddIndex(targetProperties)
+ : targetEntityType.AddIndex(targetProperties, index.Name);
+ Copy(index, clonedIndex);
+ }
+
+ targetEntityType.AddAnnotations(sourceEntityType.GetAnnotations().Where(a => !CoreAnnotationNames.AllNames.Contains(a.Name)));
+ }
+
+ protected virtual void Copy(IReadOnlyProperty sourceProperty, IMutableProperty targetProperty)
+ {
+ if (sourceProperty.FieldInfo is FieldInfo fieldInfo)
+ {
+ targetProperty.FieldInfo = fieldInfo;
+ }
+ targetProperty.IsNullable = sourceProperty.IsNullable;
+ targetProperty.IsConcurrencyToken = sourceProperty.IsConcurrencyToken;
+ targetProperty.Sentinel = sourceProperty.Sentinel;
+ targetProperty.ValueGenerated = sourceProperty.ValueGenerated;
+ targetProperty.SetPropertyAccessMode(sourceProperty.GetPropertyAccessMode());
+ targetProperty.SetBeforeSaveBehavior(sourceProperty.GetBeforeSaveBehavior());
+ targetProperty.SetAfterSaveBehavior(sourceProperty.GetAfterSaveBehavior());
+ targetProperty.SetMaxLength(sourceProperty.GetMaxLength());
+ targetProperty.SetPrecision(sourceProperty.GetPrecision());
+ targetProperty.SetScale(sourceProperty.GetScale());
+ targetProperty.SetIsUnicode(sourceProperty.IsUnicode());
+ targetProperty.SetProviderClrType(sourceProperty.GetProviderClrType());
+ targetProperty.SetValueConverter(sourceProperty.GetValueConverter());
+ targetProperty.AddAnnotations(sourceProperty.GetAnnotations().Where(a => !CoreAnnotationNames.AllNames.Contains(a.Name)));
+ }
+
+ protected virtual void Copy(IReadOnlyServiceProperty sourceProperty, IMutableServiceProperty targetProperty)
+ {
+ if (sourceProperty.FieldInfo is FieldInfo fieldInfo)
+ {
+ targetProperty.FieldInfo = fieldInfo;
+ }
+ targetProperty.SetPropertyAccessMode(sourceProperty.GetPropertyAccessMode());
+ targetProperty.AddAnnotations(sourceProperty.GetAnnotations().Where(a => !CoreAnnotationNames.AllNames.Contains(a.Name)));
+ }
+
+ protected virtual void Copy(IReadOnlyComplexProperty sourceProperty, IMutableComplexProperty targetProperty)
+ {
+ if (sourceProperty.FieldInfo is FieldInfo fieldInfo)
+ {
+ targetProperty.FieldInfo = fieldInfo;
+ }
+ targetProperty.IsNullable = sourceProperty.IsNullable;
+ targetProperty.SetPropertyAccessMode(sourceProperty.GetPropertyAccessMode());
+ targetProperty.AddAnnotations(sourceProperty.GetAnnotations().Where(a => !CoreAnnotationNames.AllNames.Contains(a.Name)));
+ Copy(sourceProperty.ComplexType, targetProperty.ComplexType);
+ }
+
+ protected virtual void Copy(IReadOnlyComplexType sourceComplexType, IMutableComplexType targetComplexType)
+ {
+ foreach (var property in sourceComplexType.GetDeclaredProperties())
+ {
+ var targetProperty = property.IsShadowProperty()
+ ? targetComplexType.AddProperty(property.Name, property.ClrType)
+ : targetComplexType.AddProperty(property.Name, property.ClrType, property.GetIdentifyingMemberInfo()!);
+ Copy(property, targetProperty);
+ }
+
+ foreach (var property in sourceComplexType.GetDeclaredComplexProperties())
+ {
+ Copy(property, targetComplexType.AddComplexProperty(
+ property.Name,
+ property.ClrType,
+ property.ComplexType.ClrType,
+ property.ComplexType.Name,
+ collection: property.IsCollection));
+ }
+
+ targetComplexType.AddAnnotations(sourceComplexType.GetAnnotations().Where(a => !CoreAnnotationNames.AllNames.Contains(a.Name)));
+ }
+
+ protected virtual void Copy(IReadOnlyKey sourceKey, IMutableKey targetKey)
+ {
+ if (sourceKey.IsPrimaryKey())
+ {
+ targetKey.DeclaringEntityType.SetPrimaryKey(targetKey.Properties);
+ }
+
+ targetKey.AddAnnotations(sourceKey.GetAnnotations().Where(a => !CoreAnnotationNames.AllNames.Contains(a.Name)));
+ }
+
+ protected virtual void Copy(IReadOnlyIndex sourceIndex, IMutableIndex targetIndex)
+ {
+ targetIndex.IsDescending = sourceIndex.IsDescending;
+ targetIndex.IsUnique = sourceIndex.IsUnique;
+ targetIndex.AddAnnotations(sourceIndex.GetAnnotations().Where(a => !CoreAnnotationNames.AllNames.Contains(a.Name)));
+ }
+
+ protected virtual void Copy(IReadOnlyForeignKey sourceForeignKey, IMutableForeignKey targetForeignKey)
+ {
+ targetForeignKey.IsUnique = sourceForeignKey.IsUnique;
+ targetForeignKey.IsRequired = sourceForeignKey.IsRequired;
+ targetForeignKey.IsRequiredDependent = sourceForeignKey.IsRequiredDependent;
+ targetForeignKey.DeleteBehavior = sourceForeignKey.DeleteBehavior;
+
+ if (sourceForeignKey.DependentToPrincipal != null)
+ {
+ var clonedNavigation = sourceForeignKey.DependentToPrincipal.IsShadowProperty()
+ ? targetForeignKey.SetDependentToPrincipal(sourceForeignKey.DependentToPrincipal.Name)
+ : targetForeignKey.SetDependentToPrincipal(sourceForeignKey.DependentToPrincipal.GetIdentifyingMemberInfo());
+ Copy(sourceForeignKey.DependentToPrincipal, clonedNavigation!);
+ }
+
+ if (sourceForeignKey.PrincipalToDependent != null)
+ {
+ var clonedNavigation = sourceForeignKey.PrincipalToDependent.IsShadowProperty()
+ ? targetForeignKey.SetPrincipalToDependent(sourceForeignKey.PrincipalToDependent.Name)
+ : targetForeignKey.SetPrincipalToDependent(sourceForeignKey.PrincipalToDependent.GetIdentifyingMemberInfo());
+ Copy(sourceForeignKey.PrincipalToDependent, clonedNavigation!);
+ }
+
+ targetForeignKey.AddAnnotations(sourceForeignKey.GetAnnotations()
+ .Where(a => !CoreAnnotationNames.AllNames.Contains(a.Name)));
+ }
+
+ protected virtual void Copy(IReadOnlyNavigation sourceNavigation, IMutableNavigation targetNavigation)
+ {
+ if (sourceNavigation.FieldInfo is FieldInfo fieldInfo)
+ {
+ targetNavigation.FieldInfo = fieldInfo;
+ }
+
+ targetNavigation.SetPropertyAccessMode(sourceNavigation.GetPropertyAccessMode());
+ targetNavigation.SetIsEagerLoaded(sourceNavigation.IsEagerLoaded);
+ targetNavigation.SetLazyLoadingEnabled(sourceNavigation.LazyLoadingEnabled);
+ targetNavigation.AddAnnotations(sourceNavigation.GetAnnotations()
+ .Where(a => !CoreAnnotationNames.AllNames.Contains(a.Name)));
+ }
+
+ protected virtual void Copy(IReadOnlySkipNavigation sourceNavigation, IMutableSkipNavigation targetNavigation)
+ {
+ if (sourceNavigation.FieldInfo is FieldInfo fieldInfo)
+ {
+ targetNavigation.FieldInfo = fieldInfo;
+ }
+
+ targetNavigation.SetPropertyAccessMode(sourceNavigation.GetPropertyAccessMode());
+ targetNavigation.SetIsEagerLoaded(sourceNavigation.IsEagerLoaded);
+ targetNavigation.SetLazyLoadingEnabled(sourceNavigation.LazyLoadingEnabled);
+ targetNavigation.AddAnnotations(sourceNavigation.GetAnnotations().Where(a => !CoreAnnotationNames.AllNames.Contains(a.Name)));
+ if (sourceNavigation.ForeignKey != null)
+ {
+ var targetDependentType = targetNavigation.DeclaringEntityType.Model.FindEntityType(
+ sourceNavigation.ForeignKey.DeclaringEntityType.Name)!;
+ var targetPrincipalType = targetNavigation.DeclaringEntityType.Model.FindEntityType(
+ sourceNavigation.ForeignKey.PrincipalEntityType.Name)!;
+ var targetKey = targetPrincipalType.FindKey(
+ sourceNavigation.ForeignKey.PrincipalKey.Properties.Select(p => targetPrincipalType.FindProperty(p.Name)!).ToList())!;
+ var targetForeignKey = targetDependentType.FindForeignKey(
+ sourceNavigation.ForeignKey.Properties.Select(p => targetDependentType.FindProperty(p.Name)!).ToList(),
+ targetKey,
+ targetPrincipalType)!;
+ targetNavigation.SetForeignKey(targetForeignKey);
+ }
+
+ if (sourceNavigation.Inverse != null)
+ {
+ var targetEntityType = targetNavigation.DeclaringEntityType.Model.FindEntityType(
+ sourceNavigation.Inverse.DeclaringEntityType.Name)!;
+ targetNavigation.SetInverse(
+ targetEntityType.FindSkipNavigation(sourceNavigation.Inverse.Name));
+ }
+ }
}
public abstract class TestModelBuilder : IInfrastructure
diff --git a/test/EFCore.Tests/ModelBuilding/NonRelationshipTestBase.cs b/test/EFCore.Tests/ModelBuilding/NonRelationshipTestBase.cs
index c0210174118..8302f96793f 100644
--- a/test/EFCore.Tests/ModelBuilding/NonRelationshipTestBase.cs
+++ b/test/EFCore.Tests/ModelBuilding/NonRelationshipTestBase.cs
@@ -16,6 +16,11 @@ public abstract partial class ModelBuilderTest
{
public abstract class NonRelationshipTestBase : ModelBuilderTestBase
{
+ public NonRelationshipTestBase(ModelBuilderFixtureBase fixture)
+ : base(fixture)
+ {
+ }
+
[ConditionalFact]
public void Can_set_model_annotation()
{
@@ -658,8 +663,7 @@ public virtual void Key_properties_cannot_be_made_optional()
CreateModelBuilder().Entity(
b =>
{
- b.HasAlternateKey(
- e => new { e.Down });
+ b.HasAlternateKey(e => new { e.Down });
b.Property(e => e.Down).IsRequired(false);
})).Message);
@@ -1920,6 +1924,7 @@ public virtual void Can_add_multiple_indexes()
entityBuilder.HasIndex(ix => ix.Id, "Descending").IsDescending();
var model = modelBuilder.FinalizeModel();
+ AssertEqual(modelBuilder.Model, model);
var entityType = model.FindEntityType(typeof(Customer))!;
var idProperty = entityType.FindProperty(nameof(Customer.Id))!;
@@ -1972,7 +1977,7 @@ public virtual void Can_set_primary_key_by_convention_for_user_specified_shadow_
entityBuilder.Property("Id");
Assert.NotNull(entityType.FindPrimaryKey());
- AssertEqual(new[] { "Id" }, entityType.FindPrimaryKey()!.Properties.Select(p => p.Name));
+ Assert.Equal(new[] { "Id" }, entityType.FindPrimaryKey()!.Properties.Select(p => p.Name));
}
[ConditionalFact]
@@ -2535,8 +2540,7 @@ public virtual void PrimitiveCollection_Key_properties_cannot_be_made_optional()
CreateModelBuilder().Entity(
b =>
{
- b.HasAlternateKey(
- e => new { e.Down });
+ b.HasAlternateKey(e => new { e.Down });
b.PrimitiveCollection(e => e.Down).IsRequired(false);
})).Message);
@@ -2935,7 +2939,7 @@ public virtual void Can_set_primary_key_by_convention_for_user_specified_shadow_
entityBuilder.PrimitiveCollection>("Id");
Assert.NotNull(entityType.FindPrimaryKey());
- AssertEqual(new[] { "Id" }, entityType.FindPrimaryKey()!.Properties.Select(p => p.Name));
+ Assert.Equal(new[] { "Id" }, entityType.FindPrimaryKey()!.Properties.Select(p => p.Name));
}
[ConditionalFact]
@@ -2994,19 +2998,21 @@ public virtual void Can_set_alternate_key_for_primitive_collection_on_an_entity_
{
b.PrimitiveCollection(e => e.CollectionCompanyId);
b.HasAlternateKey(e => e.CollectionCompanyId);
+ b.HasAlternateKey(e => e.CollectionId);
+ b.HasKey(e => e.Id);
});
- var entity = modelBuilder.Model.FindEntityType(typeof(EntityWithFields))!;
- var properties = entity.GetProperties();
- Assert.Single(properties);
- var property = properties.Single();
- Assert.Equal(nameof(EntityWithFields.CollectionCompanyId), property.Name);
+ var model = modelBuilder.FinalizeModel();
+ AssertEqual(modelBuilder.Model, model);
+
+ var entity = model.FindEntityType(typeof(EntityWithFields))!;
+ var property = entity.FindProperty(nameof(EntityWithFields.CollectionCompanyId))!;
Assert.Null(property.PropertyInfo);
Assert.NotNull(property.FieldInfo);
Assert.NotNull(property.GetElementType());
var keys = entity.GetKeys();
- var key = Assert.Single(keys);
- Assert.Equal(properties, key.Properties);
+ Assert.Equal(3, keys.Count());
+ Assert.Single(keys.Where(k => k.Properties.All(p => p == property)));
}
[ConditionalFact]
diff --git a/test/EFCore.Tests/ModelBuilding/OneToManyTestBase.cs b/test/EFCore.Tests/ModelBuilding/OneToManyTestBase.cs
index 0db49908f92..1918632e4cb 100644
--- a/test/EFCore.Tests/ModelBuilding/OneToManyTestBase.cs
+++ b/test/EFCore.Tests/ModelBuilding/OneToManyTestBase.cs
@@ -9,6 +9,11 @@ public abstract partial class ModelBuilderTest
{
public abstract class OneToManyTestBase : ModelBuilderTestBase
{
+ public OneToManyTestBase(ModelBuilderFixtureBase fixture)
+ : base(fixture)
+ {
+ }
+
[ConditionalFact]
public virtual void Finds_existing_navigations_and_uses_associated_FK()
{
@@ -899,7 +904,6 @@ public virtual void Can_use_non_PK_principal()
Assert.Same(principalKey, principalType.FindPrimaryKey());
Assert.Same(dependentKey, dependentType.FindPrimaryKey());
- expectedPrincipalProperties.Add(fk.PrincipalKey.Properties.Single());
AssertEqual(expectedPrincipalProperties, principalType.GetProperties());
expectedDependentProperties.Add(fk.Properties.Single());
AssertEqual(expectedDependentProperties, dependentType.GetProperties());
@@ -1093,9 +1097,7 @@ public virtual void Can_have_FK_by_convention_specified_with_explicit_principal_
Assert.Contains(fk.PrincipalKey, principalType.GetKeys());
Assert.NotSame(principalKey, fk.PrincipalKey);
- expectedPrincipalProperties.Add(fk.PrincipalKey.Properties.Single());
AssertEqual(expectedPrincipalProperties, principalType.GetProperties());
- expectedDependentProperties.Add(fk.Properties.Single());
AssertEqual(expectedDependentProperties, dependentType.GetProperties());
Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count());
@@ -1142,9 +1144,7 @@ public virtual void Can_have_FK_by_convention_specified_with_explicit_principal_
Assert.Contains(fk.PrincipalKey, principalType.GetKeys());
Assert.NotSame(principalKey, fk.PrincipalKey);
- expectedPrincipalProperties.Add(fk.PrincipalKey.Properties.Single());
AssertEqual(expectedPrincipalProperties, principalType.GetProperties());
- expectedDependentProperties.Add(fk.Properties.Single());
AssertEqual(expectedDependentProperties, dependentType.GetProperties());
Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count());
@@ -1191,7 +1191,6 @@ public virtual void Can_have_FK_semi_specified_with_explicit_PK()
var principalKey = principalType.FindPrimaryKey();
Assert.Same(principalKey, fk.PrincipalKey);
- expectedPrincipalProperties.Add(fk.PrincipalKey.Properties.Single());
AssertEqual(expectedPrincipalProperties, principalType.GetProperties());
var fkProperty = fk.Properties.Single();
Assert.False(fkProperty.IsNullable);
@@ -1237,7 +1236,6 @@ public virtual void Can_specify_requiredness_after_OnDelete()
var principalKey = principalType.FindPrimaryKey();
Assert.Same(principalKey, fk.PrincipalKey);
- expectedPrincipalProperties.Add(fk.PrincipalKey.Properties.Single());
AssertEqual(expectedPrincipalProperties, principalType.GetProperties());
var fkProperty = fk.Properties.Single();
Assert.False(fkProperty.IsNullable);
@@ -1394,14 +1392,13 @@ public virtual void Principal_key_by_convention_is_not_replaced_with_new_incompa
var model = modelBuilder.Model;
modelBuilder
.Entity().HasMany(e => e.Pickles).WithOne(e => e.BigMak)
- .HasForeignKey(
- e => new { e.BurgerId, e.Id });
+ .HasForeignKey(e => new { e.BurgerId, e.Id });
modelBuilder.Ignore();
var dependentType = model.FindEntityType(typeof(Pickle));
var principalType = model.FindEntityType(typeof(BigMak));
- var modelClone = modelBuilder.Model.Clone();
+ var modelClone = Clone(modelBuilder.Model);
var nonPrimaryPrincipalKey = modelClone.FindEntityType(typeof(BigMak).FullName)
.GetKeys().First(k => !k.IsPrimaryKey());
var dependentKey = dependentType.FindPrimaryKey();
@@ -1419,8 +1416,8 @@ public virtual void Principal_key_by_convention_is_not_replaced_with_new_incompa
Assert.Equal("Pickles", principalType.GetNavigations().Single().Name);
Assert.Same(fk, dependentType.GetNavigations().Single().ForeignKey);
Assert.Same(fk, principalType.GetNavigations().Single().ForeignKey);
- AssertEqual(expectedPrincipalProperties.Select(p => p.Name), principalType.GetProperties().Select(p => p.Name));
- AssertEqual(expectedDependentProperties.Select(p => p.Name), dependentType.GetProperties().Select(p => p.Name));
+ Assert.Equivalent(expectedPrincipalProperties.Select(p => p.Name), principalType.GetProperties().Select(p => p.Name));
+ AssertEqual(expectedDependentProperties, dependentType.GetProperties());
Assert.Empty(principalType.GetForeignKeys());
var primaryPrincipalKey = principalType.FindPrimaryKey();
@@ -1441,8 +1438,7 @@ public virtual void Explicit_principal_key_is_not_replaced_with_new_primary_key(
var model = modelBuilder.Model;
modelBuilder
.Entity().HasMany(e => e.Pickles).WithOne(e => e.BigMak)
- .HasPrincipalKey(
- e => new { e.Id });
+ .HasPrincipalKey(e => new { e.Id });
modelBuilder.Ignore();
var principalType = model.FindEntityType(typeof(BigMak));
@@ -1480,12 +1476,10 @@ public virtual void Creates_both_navigations_and_uses_existing_composite_FK()
{
var modelBuilder = CreateModelBuilder();
var model = modelBuilder.Model;
- modelBuilder.Entity().HasKey(
- c => new { c.Id1, c.Id2 });
+ modelBuilder.Entity().HasKey(c => new { c.Id1, c.Id2 });
modelBuilder
.Entity().HasOne(e => e.Whoopper).WithMany()
- .HasForeignKey(
- c => new { c.BurgerId1, c.BurgerId2 });
+ .HasForeignKey(c => new { c.BurgerId1, c.BurgerId2 });
modelBuilder.Ignore