diff --git a/src/EFCore.Relational/Extensions/RelationalEntityTypeExtensions.cs b/src/EFCore.Relational/Extensions/RelationalEntityTypeExtensions.cs index 58aecea0c7f..00ed23c10b6 100644 --- a/src/EFCore.Relational/Extensions/RelationalEntityTypeExtensions.cs +++ b/src/EFCore.Relational/Extensions/RelationalEntityTypeExtensions.cs @@ -147,9 +147,25 @@ public static string GetDefaultSchema([NotNull] this IEntityType entityType) return ownership.PrincipalEntityType.GetSchema(); } - return entityType.HasDefiningNavigation() - ? entityType.DefiningEntityType.GetSchema() ?? entityType.Model.GetDefaultSchema() - : entityType.Model.GetDefaultSchema(); + if (entityType.HasDefiningNavigation()) + { + return entityType.DefiningEntityType.GetSchema() ?? entityType.Model.GetDefaultSchema(); + } + else + { + var skipNavigationSchema = entityType.GetForeignKeys().SelectMany(fk => fk.GetReferencingSkipNavigations()) + .FirstOrDefault(n => !n.IsOnDependent) + ?.DeclaringEntityType.GetSchema(); + if (skipNavigationSchema != null + && entityType.GetForeignKeys().SelectMany(fk => fk.GetReferencingSkipNavigations()) + .Where(n => !n.IsOnDependent) + .All(n => n.DeclaringEntityType.GetSchema() == skipNavigationSchema)) + { + return skipNavigationSchema; + } + + return entityType.Model.GetDefaultSchema(); + } } /// diff --git a/test/EFCore.SqlServer.Tests/ModelBuilding/SqlServerModelBuilderGenericTest.cs b/test/EFCore.SqlServer.Tests/ModelBuilding/SqlServerModelBuilderGenericTest.cs index e8232508eb8..0670cdf0c13 100644 --- a/test/EFCore.SqlServer.Tests/ModelBuilding/SqlServerModelBuilderGenericTest.cs +++ b/test/EFCore.SqlServer.Tests/ModelBuilding/SqlServerModelBuilderGenericTest.cs @@ -253,6 +253,68 @@ protected override TestModelBuilder CreateModelBuilder() => CreateTestModelBuilder(SqlServerTestHelpers.Instance); } + public class SqlServerGenericManyToMany : GenericManyToMany + { + [ConditionalFact] + public virtual void Join_entity_type_uses_same_schema() + { + var modelBuilder = CreateModelBuilder(); + + modelBuilder.Entity().ToTable("Category", "mySchema").Ignore(c => c.ProductCategories); + modelBuilder.Entity().ToTable("Product", "mySchema"); + modelBuilder.Entity(); + + var model = modelBuilder.FinalizeModel(); + + var productType = model.FindEntityType(typeof(Product)); + var categoryType = model.FindEntityType(typeof(Category)); + + var categoriesNavigation = productType.GetSkipNavigations().Single(); + var productsNavigation = categoryType.GetSkipNavigations().Single(); + + var categoriesFk = categoriesNavigation.ForeignKey; + var productsFk = productsNavigation.ForeignKey; + var productCategoryType = categoriesFk.DeclaringEntityType; + + Assert.Equal(typeof(Dictionary), productCategoryType.ClrType); + Assert.Equal("mySchema", productCategoryType.GetSchema()); + Assert.Same(categoriesFk, productCategoryType.GetForeignKeys().Last()); + Assert.Same(productsFk, productCategoryType.GetForeignKeys().First()); + Assert.Equal(2, productCategoryType.GetForeignKeys().Count()); + } + + [ConditionalFact] + public virtual void Join_entity_type_uses_default_schema_if_related_are_different() + { + var modelBuilder = CreateModelBuilder(); + + modelBuilder.Entity().ToTable("Category").Ignore(c => c.ProductCategories); + modelBuilder.Entity().ToTable("Product", "dbo"); + modelBuilder.Entity(); + + var model = modelBuilder.FinalizeModel(); + + var productType = model.FindEntityType(typeof(Product)); + var categoryType = model.FindEntityType(typeof(Category)); + + var categoriesNavigation = productType.GetSkipNavigations().Single(); + var productsNavigation = categoryType.GetSkipNavigations().Single(); + + var categoriesFk = categoriesNavigation.ForeignKey; + var productsFk = productsNavigation.ForeignKey; + var productCategoryType = categoriesFk.DeclaringEntityType; + + Assert.Equal(typeof(Dictionary), productCategoryType.ClrType); + Assert.Null(productCategoryType.GetSchema()); + Assert.Same(categoriesFk, productCategoryType.GetForeignKeys().Last()); + Assert.Same(productsFk, productCategoryType.GetForeignKeys().First()); + Assert.Equal(2, productCategoryType.GetForeignKeys().Count()); + } + + protected override TestModelBuilder CreateModelBuilder() + => CreateTestModelBuilder(SqlServerTestHelpers.Instance); + } + public class SqlServerGenericOwnedTypes : GenericOwnedTypes { [ConditionalFact] diff --git a/test/EFCore.Tests/ModelBuilding/ManyToManyTestBase.cs b/test/EFCore.Tests/ModelBuilding/ManyToManyTestBase.cs index edf69db3f69..0ae0df6f845 100644 --- a/test/EFCore.Tests/ModelBuilding/ManyToManyTestBase.cs +++ b/test/EFCore.Tests/ModelBuilding/ManyToManyTestBase.cs @@ -47,12 +47,6 @@ public virtual void Discovers_navigations() Assert.Same(categoriesFk, productCategoryType.GetForeignKeys().Last()); Assert.Same(productsFk, productCategoryType.GetForeignKeys().First()); Assert.Equal(2, productCategoryType.GetForeignKeys().Count()); - - Assert.Same(categoriesNavigation, productType.GetSkipNavigations().Single()); - Assert.Same(productsNavigation, categoryType.GetSkipNavigations().Single()); - Assert.Same(categoriesFk, productCategoryType.GetForeignKeys().Last()); - Assert.Same(productsFk, productCategoryType.GetForeignKeys().First()); - Assert.Equal(2, productCategoryType.GetForeignKeys().Count()); } [ConditionalFact]