diff --git a/src/EFCore.Cosmos/Infrastructure/Internal/CosmosModelValidator.cs b/src/EFCore.Cosmos/Infrastructure/Internal/CosmosModelValidator.cs index 59e148b1537..01d72c30352 100644 --- a/src/EFCore.Cosmos/Infrastructure/Internal/CosmosModelValidator.cs +++ b/src/EFCore.Cosmos/Infrastructure/Internal/CosmosModelValidator.cs @@ -40,6 +40,7 @@ public override void Validate(IModel model, IDiagnosticsLogger @@ -431,4 +432,26 @@ protected virtual void ValidateDatabaseProperties( } } } + + /// + /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to + /// the same compatibility standards as public APIs. It may be changed or removed without notice in + /// any release. You should only use it directly in your code with extreme caution and knowing that + /// doing so can result in application failures when updating to a new Entity Framework Core release. + /// + protected virtual void ValidateIndexes( + IModel model, + IDiagnosticsLogger logger) + { + foreach (var entityType in model.GetEntityTypes()) + { + foreach (var index in entityType.GetDeclaredIndexes()) + { + throw new InvalidOperationException( + CosmosStrings.IndexesExist( + entityType.DisplayName(), + string.Join(",", index.Properties.Select(e => e.Name)))); + } + } + } } diff --git a/src/EFCore.Cosmos/Metadata/Conventions/Internal/CosmosConventionSetBuilder.cs b/src/EFCore.Cosmos/Metadata/Conventions/Internal/CosmosConventionSetBuilder.cs index 16043d00a05..8a4ffed5fe1 100644 --- a/src/EFCore.Cosmos/Metadata/Conventions/Internal/CosmosConventionSetBuilder.cs +++ b/src/EFCore.Cosmos/Metadata/Conventions/Internal/CosmosConventionSetBuilder.cs @@ -1,8 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using Microsoft.EntityFrameworkCore.Cosmos.Metadata.Internal; - namespace Microsoft.EntityFrameworkCore.Cosmos.Metadata.Conventions.Internal; /// @@ -37,6 +35,7 @@ public override ConventionSet CreateConventionSet() conventionSet.Add(new ContextContainerConvention(Dependencies)); conventionSet.Add(new ETagPropertyConvention()); conventionSet.Add(new StoreKeyConvention(Dependencies)); + conventionSet.Remove(typeof(ForeignKeyIndexConvention)); conventionSet.Replace(new CosmosValueGenerationConvention(Dependencies)); conventionSet.Replace(new CosmosKeyDiscoveryConvention(Dependencies)); diff --git a/src/EFCore.Cosmos/Properties/CosmosStrings.Designer.cs b/src/EFCore.Cosmos/Properties/CosmosStrings.Designer.cs index 75f7b0ff92e..96bd15a1e41 100644 --- a/src/EFCore.Cosmos/Properties/CosmosStrings.Designer.cs +++ b/src/EFCore.Cosmos/Properties/CosmosStrings.Designer.cs @@ -107,6 +107,14 @@ public static string IdNonStringStoreType(object? idProperty, object? entityType GetString("IdNonStringStoreType", nameof(idProperty), nameof(entityType), nameof(propertyType)), idProperty, entityType, propertyType); + /// + /// The entity type '{entityType}' has an index defined over properties '{properties}'. The Azure Cosmos DB provider for EF Core currently does not support index definitions. + /// + public static string IndexesExist(object? entityType, object? properties) + => string.Format( + GetString("IndexesExist", nameof(entityType), nameof(properties)), + entityType, properties); + /// /// The specified entity type '{derivedType}' is not derived from '{entityType}'. /// diff --git a/src/EFCore.Cosmos/Properties/CosmosStrings.resx b/src/EFCore.Cosmos/Properties/CosmosStrings.resx index 573504b97c6..421dafe913e 100644 --- a/src/EFCore.Cosmos/Properties/CosmosStrings.resx +++ b/src/EFCore.Cosmos/Properties/CosmosStrings.resx @@ -153,6 +153,9 @@ The type of the '{idProperty}' property on '{entityType}' is '{propertyType}'. All 'id' properties must be strings or have a string value converter. + + The entity type '{entityType}' has an index defined over properties '{properties}'. The Azure Cosmos DB provider for EF Core currently does not support index definitions. + The specified entity type '{derivedType}' is not derived from '{entityType}'. diff --git a/src/EFCore.InMemory/Metadata/Conventions/InMemoryConventionSetBuilder.cs b/src/EFCore.InMemory/Metadata/Conventions/InMemoryConventionSetBuilder.cs index 5ba27e45d74..0f13f38176f 100644 --- a/src/EFCore.InMemory/Metadata/Conventions/InMemoryConventionSetBuilder.cs +++ b/src/EFCore.InMemory/Metadata/Conventions/InMemoryConventionSetBuilder.cs @@ -37,6 +37,7 @@ public override ConventionSet CreateConventionSet() var conventionSet = base.CreateConventionSet(); conventionSet.Add(new DefiningQueryRewritingConvention(Dependencies)); + conventionSet.Remove(typeof(ForeignKeyIndexConvention)); return conventionSet; } diff --git a/test/EFCore.AspNet.InMemory.FunctionalTests/AspNetIdentityCustomTypesDefaultInMemoryTest.cs b/test/EFCore.AspNet.InMemory.FunctionalTests/AspNetIdentityCustomTypesDefaultInMemoryTest.cs index ee046c09e63..d51c1a2a2f7 100644 --- a/test/EFCore.AspNet.InMemory.FunctionalTests/AspNetIdentityCustomTypesDefaultInMemoryTest.cs +++ b/test/EFCore.AspNet.InMemory.FunctionalTests/AspNetIdentityCustomTypesDefaultInMemoryTest.cs @@ -11,6 +11,9 @@ protected override void UseTransaction(DatabaseFacade facade, IDbContextTransact { } + protected override bool HasForeignKeyIndexes + => false; + protected override async Task ExecuteWithStrategyInTransactionAsync( Func testOperation, Func nestedTestOperation1 = null, diff --git a/test/EFCore.AspNet.InMemory.FunctionalTests/AspNetIdentityCustomTypesIntKeyInMemoryTest.cs b/test/EFCore.AspNet.InMemory.FunctionalTests/AspNetIdentityCustomTypesIntKeyInMemoryTest.cs index 88ad5f5484a..02fb9961576 100644 --- a/test/EFCore.AspNet.InMemory.FunctionalTests/AspNetIdentityCustomTypesIntKeyInMemoryTest.cs +++ b/test/EFCore.AspNet.InMemory.FunctionalTests/AspNetIdentityCustomTypesIntKeyInMemoryTest.cs @@ -7,6 +7,9 @@ public class AspNetIdentityCustomTypesIntKeyInMemoryTest(AspNetIdentityCustomTyp : AspNetIdentityCustomTypesIntKeyTestBase< AspNetIdentityCustomTypesIntKeyInMemoryTest.AspNetIdentityCustomTypesIntKeyInMemoryFixture>(fixture) { + protected override bool HasForeignKeyIndexes + => false; + protected override void UseTransaction(DatabaseFacade facade, IDbContextTransaction transaction) { } diff --git a/test/EFCore.AspNet.InMemory.FunctionalTests/AspNetIdentityDefaultInMemoryTest.cs b/test/EFCore.AspNet.InMemory.FunctionalTests/AspNetIdentityDefaultInMemoryTest.cs index 589f1f5e0bd..c236e0155a4 100644 --- a/test/EFCore.AspNet.InMemory.FunctionalTests/AspNetIdentityDefaultInMemoryTest.cs +++ b/test/EFCore.AspNet.InMemory.FunctionalTests/AspNetIdentityDefaultInMemoryTest.cs @@ -8,6 +8,9 @@ namespace Microsoft.EntityFrameworkCore; public class AspNetIdentityDefaultInMemoryTest(AspNetIdentityDefaultInMemoryTest.AspNetDefaultIdentityInMemoryFixture fixture) : AspNetIdentityDefaultTestBase(fixture) { + protected override bool HasForeignKeyIndexes + => false; + protected override void UseTransaction(DatabaseFacade facade, IDbContextTransaction transaction) { } diff --git a/test/EFCore.AspNet.InMemory.FunctionalTests/AspNetIdentityIntKeyInMemoryTest.cs b/test/EFCore.AspNet.InMemory.FunctionalTests/AspNetIdentityIntKeyInMemoryTest.cs index 53b54a80bec..09b28ea9ade 100644 --- a/test/EFCore.AspNet.InMemory.FunctionalTests/AspNetIdentityIntKeyInMemoryTest.cs +++ b/test/EFCore.AspNet.InMemory.FunctionalTests/AspNetIdentityIntKeyInMemoryTest.cs @@ -9,6 +9,9 @@ namespace Microsoft.EntityFrameworkCore; public class AspNetIdentityIntKeyInMemoryTest(AspNetIdentityIntKeyInMemoryTest.AspNetIdentityIntKeyInMemoryFixture fixture) : AspNetIdentityIntKeyTestBase(fixture) { + protected override bool HasForeignKeyIndexes + => false; + protected override void UseTransaction(DatabaseFacade facade, IDbContextTransaction transaction) { } diff --git a/test/EFCore.AspNet.InMemory.FunctionalTests/ConfigurationDbContextInMemoryTest.cs b/test/EFCore.AspNet.InMemory.FunctionalTests/ConfigurationDbContextInMemoryTest.cs index ab1044038bd..1d57f75d63e 100644 --- a/test/EFCore.AspNet.InMemory.FunctionalTests/ConfigurationDbContextInMemoryTest.cs +++ b/test/EFCore.AspNet.InMemory.FunctionalTests/ConfigurationDbContextInMemoryTest.cs @@ -8,6 +8,9 @@ namespace Microsoft.EntityFrameworkCore; public class ConfigurationDbContextInMemoryTest(ConfigurationDbContextInMemoryTest.ConfigurationDbContextInMemoryFixture fixture) : ConfigurationDbContextTestBase(fixture) { + protected override bool HasForeignKeyIndexes + => false; + protected override void UseTransaction(DatabaseFacade facade, IDbContextTransaction transaction) { } diff --git a/test/EFCore.AspNet.InMemory.FunctionalTests/GrpcInMemoryTest.cs b/test/EFCore.AspNet.InMemory.FunctionalTests/GrpcInMemoryTest.cs index 66b89f993fc..3bdcfd197c6 100644 --- a/test/EFCore.AspNet.InMemory.FunctionalTests/GrpcInMemoryTest.cs +++ b/test/EFCore.AspNet.InMemory.FunctionalTests/GrpcInMemoryTest.cs @@ -7,6 +7,9 @@ namespace Microsoft.EntityFrameworkCore; public class GrpcInMemoryTest(GrpcInMemoryTest.GrpcInMemoryFixture fixture) : GrpcTestBase(fixture) { + protected override bool HasForeignKeyIndexes + => false; + public class GrpcInMemoryFixture : GrpcFixtureBase { protected override ITestStoreFactory TestStoreFactory diff --git a/test/EFCore.AspNet.Specification.Tests/AspNetIdentityCustomTypesDefaultTestBase.cs b/test/EFCore.AspNet.Specification.Tests/AspNetIdentityCustomTypesDefaultTestBase.cs index d02333cae0a..f81f962f170 100644 --- a/test/EFCore.AspNet.Specification.Tests/AspNetIdentityCustomTypesDefaultTestBase.cs +++ b/test/EFCore.AspNet.Specification.Tests/AspNetIdentityCustomTypesDefaultTestBase.cs @@ -170,9 +170,9 @@ protected override List ExpectedMappings "Property: CustomRoleClaimString.Id (int) Required PK AfterSave:Throw ValueGenerated.OnAdd", "Property: CustomRoleClaimString.ClaimType (string)", "Property: CustomRoleClaimString.ClaimValue (string)", - "Property: CustomRoleClaimString.RoleId (string) Required FK Index", + $"Property: CustomRoleClaimString.RoleId (string) Required FK{(HasForeignKeyIndexes ? " Index" : "")}", }, - Indexes = { "{'RoleId'} ", }, + Indexes = HasForeignKeyIndexes ? ["{'RoleId'} "] : [], FKs = { "ForeignKey: CustomRoleClaimString {'RoleId'} -> CustomRoleString {'Id'} Required Cascade ToDependent: RoleClaims ToPrincipal: Role", @@ -215,9 +215,9 @@ protected override List ExpectedMappings "Property: CustomUserClaimString.Id (int) Required PK AfterSave:Throw ValueGenerated.OnAdd", "Property: CustomUserClaimString.ClaimType (string)", "Property: CustomUserClaimString.ClaimValue (string)", - "Property: CustomUserClaimString.UserId (string) Required FK Index", + $"Property: CustomUserClaimString.UserId (string) Required FK{(HasForeignKeyIndexes ? " Index" : "")}", }, - Indexes = { "{'UserId'} ", }, + Indexes = HasForeignKeyIndexes ? ["{'UserId'} "] : [], FKs = { "ForeignKey: CustomUserClaimString {'UserId'} -> CustomUserString {'Id'} Required Cascade ToDependent: Claims ToPrincipal: User", @@ -237,9 +237,9 @@ protected override List ExpectedMappings "Property: CustomUserLoginString.LoginProvider (string) Required PK AfterSave:Throw", "Property: CustomUserLoginString.ProviderKey (string) Required PK AfterSave:Throw", "Property: CustomUserLoginString.ProviderDisplayName (string)", - "Property: CustomUserLoginString.UserId (string) Required FK Index", + $"Property: CustomUserLoginString.UserId (string) Required FK{(HasForeignKeyIndexes ? " Index" : "")}", }, - Indexes = { "{'UserId'} ", }, + Indexes = HasForeignKeyIndexes ? ["{'UserId'} "] : [], FKs = { "ForeignKey: CustomUserLoginString {'UserId'} -> CustomUserString {'Id'} Required Cascade ToDependent: Logins ToPrincipal: User", @@ -257,9 +257,9 @@ protected override List ExpectedMappings Properties = { "Property: CustomUserRoleString.UserId (string) Required PK FK AfterSave:Throw", - "Property: CustomUserRoleString.RoleId (string) Required PK FK Index AfterSave:Throw", + $"Property: CustomUserRoleString.RoleId (string) Required PK FK{(HasForeignKeyIndexes ? " Index" : "")} AfterSave:Throw", }, - Indexes = { "{'RoleId'} ", }, + Indexes = HasForeignKeyIndexes ? ["{'RoleId'} "] : [], FKs = { "ForeignKey: CustomUserRoleString {'RoleId'} -> CustomRoleString {'Id'} Required Cascade ToDependent: UserRoles ToPrincipal: Role", diff --git a/test/EFCore.AspNet.Specification.Tests/AspNetIdentityCustomTypesIntKeyTestBase.cs b/test/EFCore.AspNet.Specification.Tests/AspNetIdentityCustomTypesIntKeyTestBase.cs index 4415ed3848e..d1340188d48 100644 --- a/test/EFCore.AspNet.Specification.Tests/AspNetIdentityCustomTypesIntKeyTestBase.cs +++ b/test/EFCore.AspNet.Specification.Tests/AspNetIdentityCustomTypesIntKeyTestBase.cs @@ -58,9 +58,9 @@ protected override List ExpectedMappings "Property: CustomRoleClaimInt.Id (int) Required PK AfterSave:Throw ValueGenerated.OnAdd", "Property: CustomRoleClaimInt.ClaimType (string)", "Property: CustomRoleClaimInt.ClaimValue (string)", - "Property: CustomRoleClaimInt.RoleId (int) Required FK Index", + $"Property: CustomRoleClaimInt.RoleId (int) Required FK{(HasForeignKeyIndexes ? " Index" : "")}", }, - Indexes = { "{'RoleId'} ", }, + Indexes = HasForeignKeyIndexes ? ["{'RoleId'} "] : [], FKs = { "ForeignKey: CustomRoleClaimInt {'RoleId'} -> CustomRoleInt {'Id'} Required Cascade", }, }, new EntityTypeMapping @@ -87,9 +87,9 @@ protected override List ExpectedMappings "Property: CustomUserClaimInt.Id (int) Required PK AfterSave:Throw ValueGenerated.OnAdd", "Property: CustomUserClaimInt.ClaimType (string)", "Property: CustomUserClaimInt.ClaimValue (string)", - "Property: CustomUserClaimInt.UserId (int) Required FK Index", + $"Property: CustomUserClaimInt.UserId (int) Required FK{(HasForeignKeyIndexes ? " Index" : "")}", }, - Indexes = { "{'UserId'} ", }, + Indexes = HasForeignKeyIndexes ? ["{'UserId'} "] : [], FKs = { "ForeignKey: CustomUserClaimInt {'UserId'} -> CustomUserInt {'Id'} Required Cascade ToDependent: Claims", }, }, new EntityTypeMapping @@ -138,9 +138,9 @@ protected override List ExpectedMappings "Property: CustomUserLoginInt.LoginProvider (string) Required PK AfterSave:Throw", "Property: CustomUserLoginInt.ProviderKey (string) Required PK AfterSave:Throw", "Property: CustomUserLoginInt.ProviderDisplayName (string)", - "Property: CustomUserLoginInt.UserId (int) Required FK Index", + $"Property: CustomUserLoginInt.UserId (int) Required FK{(HasForeignKeyIndexes ? " Index" : "")}", }, - Indexes = { "{'UserId'} ", }, + Indexes = HasForeignKeyIndexes ? ["{'UserId'} "] : [], FKs = { "ForeignKey: CustomUserLoginInt {'UserId'} -> CustomUserInt {'Id'} Required Cascade ToDependent: Logins", }, }, new EntityTypeMapping @@ -151,9 +151,9 @@ protected override List ExpectedMappings Properties = { "Property: CustomUserRoleInt.UserId (int) Required PK FK AfterSave:Throw", - "Property: CustomUserRoleInt.RoleId (int) Required PK FK Index AfterSave:Throw", + $"Property: CustomUserRoleInt.RoleId (int) Required PK FK{(HasForeignKeyIndexes ? " Index" : "")} AfterSave:Throw", }, - Indexes = { "{'RoleId'} ", }, + Indexes = HasForeignKeyIndexes ? ["{'RoleId'} "] : [], FKs = { "ForeignKey: CustomUserRoleInt {'RoleId'} -> CustomRoleInt {'Id'} Required Cascade", diff --git a/test/EFCore.AspNet.Specification.Tests/AspNetIdentityDefaultTestBase.cs b/test/EFCore.AspNet.Specification.Tests/AspNetIdentityDefaultTestBase.cs index ed35ae64cf5..a2f1fa2e320 100644 --- a/test/EFCore.AspNet.Specification.Tests/AspNetIdentityDefaultTestBase.cs +++ b/test/EFCore.AspNet.Specification.Tests/AspNetIdentityDefaultTestBase.cs @@ -44,9 +44,9 @@ protected override List ExpectedMappings "Property: IdentityRoleClaim.Id (int) Required PK AfterSave:Throw ValueGenerated.OnAdd", "Property: IdentityRoleClaim.ClaimType (string)", "Property: IdentityRoleClaim.ClaimValue (string)", - "Property: IdentityRoleClaim.RoleId (string) Required FK Index", + $"Property: IdentityRoleClaim.RoleId (string) Required FK{(HasForeignKeyIndexes ? " Index" : "")}", }, - Indexes = { "{'RoleId'} ", }, + Indexes = HasForeignKeyIndexes ? ["{'RoleId'} "] : [], FKs = { "ForeignKey: IdentityRoleClaim {'RoleId'} -> IdentityRole {'Id'} Required Cascade", }, }, new EntityTypeMapping @@ -87,9 +87,9 @@ protected override List ExpectedMappings "Property: IdentityUserClaim.Id (int) Required PK AfterSave:Throw ValueGenerated.OnAdd", "Property: IdentityUserClaim.ClaimType (string)", "Property: IdentityUserClaim.ClaimValue (string)", - "Property: IdentityUserClaim.UserId (string) Required FK Index", + $"Property: IdentityUserClaim.UserId (string) Required FK{(HasForeignKeyIndexes ? " Index" : "")}", }, - Indexes = { "{'UserId'} ", }, + Indexes = HasForeignKeyIndexes ? ["{'UserId'} "] : [], FKs = { "ForeignKey: IdentityUserClaim {'UserId'} -> IdentityUser {'Id'} Required Cascade", }, }, new EntityTypeMapping @@ -102,9 +102,9 @@ protected override List ExpectedMappings "Property: IdentityUserLogin.LoginProvider (string) Required PK AfterSave:Throw", "Property: IdentityUserLogin.ProviderKey (string) Required PK AfterSave:Throw", "Property: IdentityUserLogin.ProviderDisplayName (string)", - "Property: IdentityUserLogin.UserId (string) Required FK Index", + $"Property: IdentityUserLogin.UserId (string) Required FK{(HasForeignKeyIndexes ? " Index" : "")}", }, - Indexes = { "{'UserId'} ", }, + Indexes = HasForeignKeyIndexes ? ["{'UserId'} "] : [], FKs = { "ForeignKey: IdentityUserLogin {'UserId'} -> IdentityUser {'Id'} Required Cascade", }, }, new EntityTypeMapping @@ -115,9 +115,9 @@ protected override List ExpectedMappings Properties = { "Property: IdentityUserRole.UserId (string) Required PK FK AfterSave:Throw", - "Property: IdentityUserRole.RoleId (string) Required PK FK Index AfterSave:Throw", + $"Property: IdentityUserRole.RoleId (string) Required PK FK{(HasForeignKeyIndexes ? " Index" : "")} AfterSave:Throw", }, - Indexes = { "{'RoleId'} ", }, + Indexes = HasForeignKeyIndexes ? ["{'RoleId'} "] : [], FKs = { "ForeignKey: IdentityUserRole {'RoleId'} -> IdentityRole {'Id'} Required Cascade", diff --git a/test/EFCore.AspNet.Specification.Tests/AspNetIdentityIntKeyTestBase.cs b/test/EFCore.AspNet.Specification.Tests/AspNetIdentityIntKeyTestBase.cs index 4e40dca3841..d6a61e858dc 100644 --- a/test/EFCore.AspNet.Specification.Tests/AspNetIdentityIntKeyTestBase.cs +++ b/test/EFCore.AspNet.Specification.Tests/AspNetIdentityIntKeyTestBase.cs @@ -46,9 +46,9 @@ protected override List ExpectedMappings "Property: IdentityRoleClaim.Id (int) Required PK AfterSave:Throw ValueGenerated.OnAdd", "Property: IdentityRoleClaim.ClaimType (string)", "Property: IdentityRoleClaim.ClaimValue (string)", - "Property: IdentityRoleClaim.RoleId (int) Required FK Index", + $"Property: IdentityRoleClaim.RoleId (int) Required FK{(HasForeignKeyIndexes ? " Index" : "")}", }, - Indexes = { "{'RoleId'} ", }, + Indexes = HasForeignKeyIndexes ? ["{'RoleId'} "] : [], FKs = { "ForeignKey: IdentityRoleClaim {'RoleId'} -> IdentityRole {'Id'} Required Cascade", }, }, new EntityTypeMapping @@ -89,9 +89,9 @@ protected override List ExpectedMappings "Property: IdentityUserClaim.Id (int) Required PK AfterSave:Throw ValueGenerated.OnAdd", "Property: IdentityUserClaim.ClaimType (string)", "Property: IdentityUserClaim.ClaimValue (string)", - "Property: IdentityUserClaim.UserId (int) Required FK Index", + $"Property: IdentityUserClaim.UserId (int) Required FK{(HasForeignKeyIndexes ? " Index" : "")}", }, - Indexes = { "{'UserId'} ", }, + Indexes = HasForeignKeyIndexes ? ["{'UserId'} "] : [], FKs = { "ForeignKey: IdentityUserClaim {'UserId'} -> IdentityUser {'Id'} Required Cascade", }, }, new EntityTypeMapping @@ -104,9 +104,9 @@ protected override List ExpectedMappings "Property: IdentityUserLogin.LoginProvider (string) Required PK AfterSave:Throw", "Property: IdentityUserLogin.ProviderKey (string) Required PK AfterSave:Throw", "Property: IdentityUserLogin.ProviderDisplayName (string)", - "Property: IdentityUserLogin.UserId (int) Required FK Index", + $"Property: IdentityUserLogin.UserId (int) Required FK{(HasForeignKeyIndexes ? " Index" : "")}", }, - Indexes = { "{'UserId'} ", }, + Indexes = HasForeignKeyIndexes ? ["{'UserId'} "] : [], FKs = { "ForeignKey: IdentityUserLogin {'UserId'} -> IdentityUser {'Id'} Required Cascade", }, }, new EntityTypeMapping @@ -117,9 +117,9 @@ protected override List ExpectedMappings Properties = { "Property: IdentityUserRole.UserId (int) Required PK FK AfterSave:Throw", - "Property: IdentityUserRole.RoleId (int) Required PK FK Index AfterSave:Throw", + $"Property: IdentityUserRole.RoleId (int) Required PK FK{(HasForeignKeyIndexes ? " Index" : "")} AfterSave:Throw", }, - Indexes = { "{'RoleId'} ", }, + Indexes = HasForeignKeyIndexes ? ["{'RoleId'} "] : [], FKs = { "ForeignKey: IdentityUserRole {'RoleId'} -> IdentityRole {'Id'} Required Cascade", diff --git a/test/EFCore.AspNet.Specification.Tests/AspNetIdentityTestBase.cs b/test/EFCore.AspNet.Specification.Tests/AspNetIdentityTestBase.cs index f9899d85133..447502c4246 100644 --- a/test/EFCore.AspNet.Specification.Tests/AspNetIdentityTestBase.cs +++ b/test/EFCore.AspNet.Specification.Tests/AspNetIdentityTestBase.cs @@ -27,6 +27,9 @@ protected AspNetIdentityTestBase(TFixture fixture) Fixture = fixture; } + protected virtual bool HasForeignKeyIndexes + => true; + [ConditionalFact] public void Can_build_identity_model() { diff --git a/test/EFCore.AspNet.Specification.Tests/ConfigurationDbContextTestBase.cs b/test/EFCore.AspNet.Specification.Tests/ConfigurationDbContextTestBase.cs index 6ab75381f4d..8e5c468e1a4 100644 --- a/test/EFCore.AspNet.Specification.Tests/ConfigurationDbContextTestBase.cs +++ b/test/EFCore.AspNet.Specification.Tests/ConfigurationDbContextTestBase.cs @@ -18,6 +18,9 @@ protected ConfigurationDbContextTestBase(ConfigurationDbContextFixtureBase fixtu protected ConfigurationDbContextFixtureBase Fixture { get; } + protected virtual bool HasForeignKeyIndexes + => true; + [ConditionalFact( Skip = "VerificationException : Method System.Linq.Enumerable.MaxFloat: type argument 'System.Char' violates the constraint of type parameter 'T'.")] @@ -283,10 +286,10 @@ protected virtual List ExpectedMappings Properties = { "Property: ApiResourceClaim.Id (int) Required PK AfterSave:Throw ValueGenerated.OnAdd", - "Property: ApiResourceClaim.ApiResourceId (int) Required FK Index", + $"Property: ApiResourceClaim.ApiResourceId (int) Required FK{(HasForeignKeyIndexes ? " Index" : "")}", "Property: ApiResourceClaim.Type (string) Required MaxLength(200)", }, - Indexes = { "{'ApiResourceId'} ", }, + Indexes = HasForeignKeyIndexes ? ["{'ApiResourceId'} "] : [], FKs = { "ForeignKey: ApiResourceClaim {'ApiResourceId'} -> ApiResource {'Id'} Required Cascade ToDependent: UserClaims ToPrincipal: ApiResource", @@ -301,11 +304,11 @@ protected virtual List ExpectedMappings Properties = { "Property: ApiResourceProperty.Id (int) Required PK AfterSave:Throw ValueGenerated.OnAdd", - "Property: ApiResourceProperty.ApiResourceId (int) Required FK Index", + $"Property: ApiResourceProperty.ApiResourceId (int) Required FK{(HasForeignKeyIndexes ? " Index" : "")}", "Property: ApiResourceProperty.Key (string) Required MaxLength(250)", "Property: ApiResourceProperty.Value (string) Required MaxLength(2000)", }, - Indexes = { "{'ApiResourceId'} ", }, + Indexes = HasForeignKeyIndexes ? ["{'ApiResourceId'} "] : [], FKs = { "ForeignKey: ApiResourceProperty {'ApiResourceId'} -> ApiResource {'Id'} Required Cascade ToDependent: Properties ToPrincipal: ApiResource", @@ -320,10 +323,10 @@ protected virtual List ExpectedMappings Properties = { "Property: ApiResourceScope.Id (int) Required PK AfterSave:Throw ValueGenerated.OnAdd", - "Property: ApiResourceScope.ApiResourceId (int) Required FK Index", + $"Property: ApiResourceScope.ApiResourceId (int) Required FK{(HasForeignKeyIndexes ? " Index" : "")}", "Property: ApiResourceScope.Scope (string) Required MaxLength(200)", }, - Indexes = { "{'ApiResourceId'} ", }, + Indexes = HasForeignKeyIndexes ? ["{'ApiResourceId'} "] : [], FKs = { "ForeignKey: ApiResourceScope {'ApiResourceId'} -> ApiResource {'Id'} Required Cascade ToDependent: Scopes ToPrincipal: ApiResource", @@ -338,14 +341,14 @@ protected virtual List ExpectedMappings Properties = { "Property: ApiResourceSecret.Id (int) Required PK AfterSave:Throw ValueGenerated.OnAdd", - "Property: ApiResourceSecret.ApiResourceId (int) Required FK Index", + $"Property: ApiResourceSecret.ApiResourceId (int) Required FK{(HasForeignKeyIndexes ? " Index" : "")}", "Property: ApiResourceSecret.Created (DateTime) Required", "Property: ApiResourceSecret.Description (string) MaxLength(1000)", "Property: ApiResourceSecret.Expiration (DateTime?)", "Property: ApiResourceSecret.Type (string) Required MaxLength(250)", "Property: ApiResourceSecret.Value (string) Required MaxLength(4000)", }, - Indexes = { "{'ApiResourceId'} ", }, + Indexes = HasForeignKeyIndexes ? ["{'ApiResourceId'} "] : [], FKs = { "ForeignKey: ApiResourceSecret {'ApiResourceId'} -> ApiResource {'Id'} Required Cascade ToDependent: Secrets ToPrincipal: ApiResource", @@ -383,10 +386,10 @@ protected virtual List ExpectedMappings Properties = { "Property: ApiScopeClaim.Id (int) Required PK AfterSave:Throw ValueGenerated.OnAdd", - "Property: ApiScopeClaim.ScopeId (int) Required FK Index", + $"Property: ApiScopeClaim.ScopeId (int) Required FK{(HasForeignKeyIndexes ? " Index" : "")}", "Property: ApiScopeClaim.Type (string) Required MaxLength(200)", }, - Indexes = { "{'ScopeId'} ", }, + Indexes = HasForeignKeyIndexes ? ["{'ScopeId'} "] : [], FKs = { "ForeignKey: ApiScopeClaim {'ScopeId'} -> ApiScope {'Id'} Required Cascade ToDependent: UserClaims ToPrincipal: Scope", @@ -402,10 +405,10 @@ protected virtual List ExpectedMappings { "Property: ApiScopeProperty.Id (int) Required PK AfterSave:Throw ValueGenerated.OnAdd", "Property: ApiScopeProperty.Key (string) Required MaxLength(250)", - "Property: ApiScopeProperty.ScopeId (int) Required FK Index", + $"Property: ApiScopeProperty.ScopeId (int) Required FK{(HasForeignKeyIndexes ? " Index" : "")}", "Property: ApiScopeProperty.Value (string) Required MaxLength(2000)", }, - Indexes = { "{'ScopeId'} ", }, + Indexes = HasForeignKeyIndexes ? ["{'ScopeId'} "] : [], FKs = { "ForeignKey: ApiScopeProperty {'ScopeId'} -> ApiScope {'Id'} Required Cascade ToDependent: Properties ToPrincipal: Scope", @@ -486,11 +489,11 @@ protected virtual List ExpectedMappings Properties = { "Property: ClientClaim.Id (int) Required PK AfterSave:Throw ValueGenerated.OnAdd", - "Property: ClientClaim.ClientId (int) Required FK Index", + $"Property: ClientClaim.ClientId (int) Required FK{(HasForeignKeyIndexes ? " Index" : "")}", "Property: ClientClaim.Type (string) Required MaxLength(250)", "Property: ClientClaim.Value (string) Required MaxLength(250)", }, - Indexes = { "{'ClientId'} ", }, + Indexes = HasForeignKeyIndexes ? ["{'ClientId'} "] : [], FKs = { "ForeignKey: ClientClaim {'ClientId'} -> Client {'Id'} Required Cascade ToDependent: Claims ToPrincipal: Client", }, Navigations = { "Navigation: ClientClaim.Client (Client) ToPrincipal Client Inverse: Claims", }, }, @@ -502,10 +505,10 @@ protected virtual List ExpectedMappings Properties = { "Property: ClientCorsOrigin.Id (int) Required PK AfterSave:Throw ValueGenerated.OnAdd", - "Property: ClientCorsOrigin.ClientId (int) Required FK Index", + $"Property: ClientCorsOrigin.ClientId (int) Required FK{(HasForeignKeyIndexes ? " Index" : "")}", "Property: ClientCorsOrigin.Origin (string) Required MaxLength(150)", }, - Indexes = { "{'ClientId'} ", }, + Indexes = HasForeignKeyIndexes ? ["{'ClientId'} "] : [], FKs = { "ForeignKey: ClientCorsOrigin {'ClientId'} -> Client {'Id'} Required Cascade ToDependent: AllowedCorsOrigins ToPrincipal: Client", @@ -520,10 +523,10 @@ protected virtual List ExpectedMappings Properties = { "Property: ClientGrantType.Id (int) Required PK AfterSave:Throw ValueGenerated.OnAdd", - "Property: ClientGrantType.ClientId (int) Required FK Index", + $"Property: ClientGrantType.ClientId (int) Required FK{(HasForeignKeyIndexes ? " Index" : "")}", "Property: ClientGrantType.GrantType (string) Required MaxLength(250)", }, - Indexes = { "{'ClientId'} ", }, + Indexes = HasForeignKeyIndexes ? ["{'ClientId'} "] : [], FKs = { "ForeignKey: ClientGrantType {'ClientId'} -> Client {'Id'} Required Cascade ToDependent: AllowedGrantTypes ToPrincipal: Client", @@ -538,10 +541,10 @@ protected virtual List ExpectedMappings Properties = { "Property: ClientIdPRestriction.Id (int) Required PK AfterSave:Throw ValueGenerated.OnAdd", - "Property: ClientIdPRestriction.ClientId (int) Required FK Index", + $"Property: ClientIdPRestriction.ClientId (int) Required FK{(HasForeignKeyIndexes ? " Index" : "")}", "Property: ClientIdPRestriction.Provider (string) Required MaxLength(200)", }, - Indexes = { "{'ClientId'} ", }, + Indexes = HasForeignKeyIndexes ? ["{'ClientId'} "] : [], FKs = { "ForeignKey: ClientIdPRestriction {'ClientId'} -> Client {'Id'} Required Cascade ToDependent: IdentityProviderRestrictions ToPrincipal: Client", @@ -559,10 +562,10 @@ protected virtual List ExpectedMappings Properties = { "Property: ClientPostLogoutRedirectUri.Id (int) Required PK AfterSave:Throw ValueGenerated.OnAdd", - "Property: ClientPostLogoutRedirectUri.ClientId (int) Required FK Index", + $"Property: ClientPostLogoutRedirectUri.ClientId (int) Required FK{(HasForeignKeyIndexes ? " Index" : "")}", "Property: ClientPostLogoutRedirectUri.PostLogoutRedirectUri (string) Required MaxLength(2000)", }, - Indexes = { "{'ClientId'} ", }, + Indexes = HasForeignKeyIndexes ? ["{'ClientId'} "] : [], FKs = { "ForeignKey: ClientPostLogoutRedirectUri {'ClientId'} -> Client {'Id'} Required Cascade ToDependent: PostLogoutRedirectUris ToPrincipal: Client", @@ -580,11 +583,11 @@ protected virtual List ExpectedMappings Properties = { "Property: ClientProperty.Id (int) Required PK AfterSave:Throw ValueGenerated.OnAdd", - "Property: ClientProperty.ClientId (int) Required FK Index", + $"Property: ClientProperty.ClientId (int) Required FK{(HasForeignKeyIndexes ? " Index" : "")}", "Property: ClientProperty.Key (string) Required MaxLength(250)", "Property: ClientProperty.Value (string) Required MaxLength(2000)", }, - Indexes = { "{'ClientId'} ", }, + Indexes = HasForeignKeyIndexes ? ["{'ClientId'} "] : [], FKs = { "ForeignKey: ClientProperty {'ClientId'} -> Client {'Id'} Required Cascade ToDependent: Properties ToPrincipal: Client", @@ -599,10 +602,10 @@ protected virtual List ExpectedMappings Properties = { "Property: ClientRedirectUri.Id (int) Required PK AfterSave:Throw ValueGenerated.OnAdd", - "Property: ClientRedirectUri.ClientId (int) Required FK Index", + $"Property: ClientRedirectUri.ClientId (int) Required FK{(HasForeignKeyIndexes ? " Index" : "")}", "Property: ClientRedirectUri.RedirectUri (string) Required MaxLength(2000)", }, - Indexes = { "{'ClientId'} ", }, + Indexes = HasForeignKeyIndexes ? ["{'ClientId'} "] : [], FKs = { "ForeignKey: ClientRedirectUri {'ClientId'} -> Client {'Id'} Required Cascade ToDependent: RedirectUris ToPrincipal: Client", @@ -617,10 +620,10 @@ protected virtual List ExpectedMappings Properties = { "Property: ClientScope.Id (int) Required PK AfterSave:Throw ValueGenerated.OnAdd", - "Property: ClientScope.ClientId (int) Required FK Index", + $"Property: ClientScope.ClientId (int) Required FK{(HasForeignKeyIndexes ? " Index" : "")}", "Property: ClientScope.Scope (string) Required MaxLength(200)", }, - Indexes = { "{'ClientId'} ", }, + Indexes = HasForeignKeyIndexes ? ["{'ClientId'} "] : [], FKs = { "ForeignKey: ClientScope {'ClientId'} -> Client {'Id'} Required Cascade ToDependent: AllowedScopes ToPrincipal: Client", @@ -635,14 +638,14 @@ protected virtual List ExpectedMappings Properties = { "Property: ClientSecret.Id (int) Required PK AfterSave:Throw ValueGenerated.OnAdd", - "Property: ClientSecret.ClientId (int) Required FK Index", + $"Property: ClientSecret.ClientId (int) Required FK{(HasForeignKeyIndexes ? " Index" : "")}", "Property: ClientSecret.Created (DateTime) Required", "Property: ClientSecret.Description (string) MaxLength(2000)", "Property: ClientSecret.Expiration (DateTime?)", "Property: ClientSecret.Type (string) Required MaxLength(250)", "Property: ClientSecret.Value (string) Required MaxLength(4000)", }, - Indexes = { "{'ClientId'} ", }, + Indexes = HasForeignKeyIndexes ? ["{'ClientId'} "] : [], FKs = { "ForeignKey: ClientSecret {'ClientId'} -> Client {'Id'} Required Cascade ToDependent: ClientSecrets ToPrincipal: Client", @@ -683,10 +686,10 @@ protected virtual List ExpectedMappings Properties = { "Property: IdentityResourceClaim.Id (int) Required PK AfterSave:Throw ValueGenerated.OnAdd", - "Property: IdentityResourceClaim.IdentityResourceId (int) Required FK Index", + $"Property: IdentityResourceClaim.IdentityResourceId (int) Required FK{(HasForeignKeyIndexes ? " Index" : "")}", "Property: IdentityResourceClaim.Type (string) Required MaxLength(200)", }, - Indexes = { "{'IdentityResourceId'} ", }, + Indexes = HasForeignKeyIndexes ? ["{'IdentityResourceId'} "] : [], FKs = { "ForeignKey: IdentityResourceClaim {'IdentityResourceId'} -> IdentityResource {'Id'} Required Cascade ToDependent: UserClaims ToPrincipal: IdentityResource", @@ -704,11 +707,11 @@ protected virtual List ExpectedMappings Properties = { "Property: IdentityResourceProperty.Id (int) Required PK AfterSave:Throw ValueGenerated.OnAdd", - "Property: IdentityResourceProperty.IdentityResourceId (int) Required FK Index", + $"Property: IdentityResourceProperty.IdentityResourceId (int) Required FK{(HasForeignKeyIndexes ? " Index" : "")}", "Property: IdentityResourceProperty.Key (string) Required MaxLength(250)", "Property: IdentityResourceProperty.Value (string) Required MaxLength(2000)", }, - Indexes = { "{'IdentityResourceId'} ", }, + Indexes = HasForeignKeyIndexes ? ["{'IdentityResourceId'} "] : [], FKs = { "ForeignKey: IdentityResourceProperty {'IdentityResourceId'} -> IdentityResource {'Id'} Required Cascade ToDependent: Properties ToPrincipal: IdentityResource", diff --git a/test/EFCore.AspNet.Specification.Tests/GrpcTestBase.cs b/test/EFCore.AspNet.Specification.Tests/GrpcTestBase.cs index 772d861bc5c..77a659dee9b 100644 --- a/test/EFCore.AspNet.Specification.Tests/GrpcTestBase.cs +++ b/test/EFCore.AspNet.Specification.Tests/GrpcTestBase.cs @@ -18,6 +18,9 @@ protected GrpcTestBase(TFixture fixture) protected TFixture Fixture { get; } + protected virtual bool HasForeignKeyIndexes + => true; + protected List ExpectedMappings => new() { @@ -30,9 +33,9 @@ protected List ExpectedMappings Properties = { "Property: PostTag (Dictionary).PostsInTagDataPostId (no field, int) Indexer Required PK FK AfterSave:Throw", - "Property: PostTag (Dictionary).TagsInPostDataTagId (no field, int) Indexer Required PK FK Index AfterSave:Throw", + $"Property: PostTag (Dictionary).TagsInPostDataTagId (no field, int) Indexer Required PK FK{(HasForeignKeyIndexes ? " Index" : "")} AfterSave:Throw", }, - Indexes = { "{'TagsInPostDataTagId'} ", }, + Indexes = HasForeignKeyIndexes ? ["{'TagsInPostDataTagId'} "] : [], FKs = { "ForeignKey: PostTag (Dictionary) {'PostsInTagDataPostId'} -> Post {'PostId'} Required Cascade", @@ -59,12 +62,12 @@ protected List ExpectedMappings Properties = { "Property: Post.PostId (postId_, int) Required PK AfterSave:Throw ValueGenerated.OnAdd", - "Property: Post.AuthorId (authorId_, int) Required FK Index", + $"Property: Post.AuthorId (authorId_, int) Required FK{(HasForeignKeyIndexes ? " Index" : "")}", "Property: Post.DateCreated (dateCreated_, Timestamp)", "Property: Post.PostStat (postStat_, PostStatus) Required", "Property: Post.Title (title_, string)", }, - Indexes = { "{'AuthorId'} ", }, + Indexes = HasForeignKeyIndexes ? ["{'AuthorId'} "] : [], FKs = { "ForeignKey: Post {'AuthorId'} -> Author {'AuthorId'} Required Cascade ToPrincipal: PostAuthor", }, Navigations = { "Navigation: Post.PostAuthor (postAuthor_, Author) ToPrincipal Author", }, SkipNavigations = diff --git a/test/EFCore.AspNet.Specification.Tests/TestUtilities/EntityTypeMapping.cs b/test/EFCore.AspNet.Specification.Tests/TestUtilities/EntityTypeMapping.cs index 6d4be04fea7..9643a28c81e 100644 --- a/test/EFCore.AspNet.Specification.Tests/TestUtilities/EntityTypeMapping.cs +++ b/test/EFCore.AspNet.Specification.Tests/TestUtilities/EntityTypeMapping.cs @@ -36,7 +36,7 @@ public EntityTypeMapping(IEntityType entityType) public string TableName { get; set; } public string PrimaryKey { get; set; } public List Properties { get; } = []; - public List Indexes { get; } = []; + public List Indexes { get; set; } = []; public List FKs { get; } = []; public List Navigations { get; } = []; public List SkipNavigations { get; } = []; diff --git a/test/EFCore.Cosmos.FunctionalTests/CustomConvertersCosmosTest.cs b/test/EFCore.Cosmos.FunctionalTests/CustomConvertersCosmosTest.cs index cd96d45af64..d1e2fcf12ad 100644 --- a/test/EFCore.Cosmos.FunctionalTests/CustomConvertersCosmosTest.cs +++ b/test/EFCore.Cosmos.FunctionalTests/CustomConvertersCosmosTest.cs @@ -190,6 +190,9 @@ protected override void OnModelCreating(ModelBuilder modelBuilder, DbContext con nullableShadowJObject.SetConfigurationSource(ConfigurationSource.Convention); modelBuilder.Entity(b => b.ToContainer("SimpleCounters")); + + modelBuilder.Entity().Metadata.RemoveIndex( + modelBuilder.Entity().Property(e => e.SSN).Metadata.GetContainingIndexes().Single()); } } } diff --git a/test/EFCore.Cosmos.FunctionalTests/ModelBuilding/CosmosModelBuilderGenericTest.cs b/test/EFCore.Cosmos.FunctionalTests/ModelBuilding/CosmosModelBuilderGenericTest.cs index 4b609fa503e..1eedaa164ca 100644 --- a/test/EFCore.Cosmos.FunctionalTests/ModelBuilding/CosmosModelBuilderGenericTest.cs +++ b/test/EFCore.Cosmos.FunctionalTests/ModelBuilding/CosmosModelBuilderGenericTest.cs @@ -11,6 +11,42 @@ public class CosmosModelBuilderGenericTest : ModelBuilderTest { public class CosmosGenericNonRelationship(CosmosModelBuilderFixture fixture) : NonRelationshipTestBase(fixture), IClassFixture { + public override void Can_add_contained_indexes() + => Assert.Equal( + CosmosStrings.IndexesExist(nameof(Customer), "Id"), + Assert.Throws( + base.Can_add_contained_indexes).Message); + + public override void Can_add_index() + => Assert.Equal( + CosmosStrings.IndexesExist(nameof(Customer), "Name"), + Assert.Throws( + base.Can_add_index).Message); + + public override void Can_add_index_when_no_clr_property() + => Assert.Equal( + CosmosStrings.IndexesExist(nameof(Customer), "Index"), + Assert.Throws( + base.Can_add_index_when_no_clr_property).Message); + + public override void Can_add_multiple_indexes() + => Assert.Equal( + CosmosStrings.IndexesExist(nameof(Customer), "Id"), + Assert.Throws( + base.Can_add_multiple_indexes).Message); + + public override void Can_set_composite_index_on_an_entity_with_fields() + => Assert.Equal( + CosmosStrings.IndexesExist(nameof(EntityWithFields), "TenantId,CompanyId"), + Assert.Throws( + base.Can_set_composite_index_on_an_entity_with_fields).Message); + + public override void Can_set_index_on_an_entity_with_fields() + => Assert.Equal( + CosmosStrings.IndexesExist(nameof(EntityWithFields), "CompanyId"), + Assert.Throws( + base.Can_set_index_on_an_entity_with_fields).Message); + public override void Properties_can_set_row_version() => Assert.Equal( CosmosStrings.NonETagConcurrencyToken(nameof(Quarks), "Charm"), @@ -564,6 +600,12 @@ protected override TestModelBuilder CreateModelBuilder(Action { + public override void Creates_overlapping_foreign_keys_with_different_nullability() + => Assert.Equal( + CosmosStrings.IndexesExist(nameof(Product), "Id,OrderId"), + Assert.Throws( + base.Creates_overlapping_foreign_keys_with_different_nullability).Message); + public override void Navigation_to_shared_type_is_not_discovered_by_convention() { var modelBuilder = CreateModelBuilder(); @@ -921,6 +963,48 @@ public override void Configuring_base_type_as_owned_throws() "No exception was thrown", Assert.Throws(base.Deriving_from_owned_type_throws).Message); + public override void Can_configure_one_to_many_owned_type_with_fields() + => Assert.Equal( + CosmosStrings.IndexesExist(nameof(OneToManyOwnedWithField), "OneToManyOwnerId"), + Assert.Throws( + base.Can_configure_one_to_many_owned_type_with_fields).Message); + + public override void Can_configure_one_to_one_owned_type_with_fields() + => Assert.Equal( + CosmosStrings.IndexesExist(nameof(OneToOneOwnedWithField), "OneToOneOwnerId"), + Assert.Throws( + base.Can_configure_one_to_one_owned_type_with_fields).Message); + + public override void Can_configure_owned_type() + => Assert.Equal( + CosmosStrings.IndexesExist(nameof(CustomerDetails), "CustomerId"), + Assert.Throws( + base.Can_configure_owned_type).Message); + + public override void Can_configure_owned_type_collection() + => Assert.Equal( + CosmosStrings.IndexesExist(nameof(Order), "foo"), + Assert.Throws( + base.Can_configure_owned_type_collection).Message); + + public override void Can_configure_owned_type_collection_using_nested_closure() + => Assert.Equal( + CosmosStrings.IndexesExist(nameof(Order), "AnotherCustomerId"), + Assert.Throws( + base.Can_configure_owned_type_collection_using_nested_closure).Message); + + public override void Can_configure_chained_ownerships() + => Assert.Equal( + CosmosStrings.IndexesExist("Book.Label#BookLabel.AnotherBookLabel#AnotherBookLabel.SpecialBookLabel#SpecialBookLabel", "BookId"), + Assert.Throws( + base.Can_configure_chained_ownerships).Message); + + public override void Shared_type_entity_types_with_FK_to_another_entity_works() + => Assert.Equal( + CosmosStrings.IndexesExist("BillingOwner.Bill1#BillingDetail", "Country"), + Assert.Throws( + base.Shared_type_entity_types_with_FK_to_another_entity_works).Message); + [ConditionalFact] public virtual void Reference_type_is_discovered_as_owned() { @@ -957,5 +1041,7 @@ protected override TestModelBuilder CreateModelBuilder(Action CosmosTestHelpers.Instance; + public override bool ForeignKeysHaveIndexes + => false; } } diff --git a/test/EFCore.Cosmos.FunctionalTests/Query/NorthwindQueryCosmosFixture.cs b/test/EFCore.Cosmos.FunctionalTests/Query/NorthwindQueryCosmosFixture.cs index 748a0c8eb5f..e8fb657be4b 100644 --- a/test/EFCore.Cosmos.FunctionalTests/Query/NorthwindQueryCosmosFixture.cs +++ b/test/EFCore.Cosmos.FunctionalTests/Query/NorthwindQueryCosmosFixture.cs @@ -51,5 +51,23 @@ protected override void OnModelCreating(ModelBuilder modelBuilder, DbContext con modelBuilder .Entity() .HasDiscriminator("Discriminator").HasValue("Customer"); + + modelBuilder.Entity().Metadata.RemoveIndex( + modelBuilder.Entity().Property(e => e.City).Metadata.GetContainingIndexes().Single()); + + modelBuilder.Entity().Metadata.RemoveIndex( + modelBuilder.Entity().Property(e => e.CompanyName).Metadata.GetContainingIndexes().Single()); + + modelBuilder.Entity().Metadata.RemoveIndex( + modelBuilder.Entity().Property(e => e.PostalCode).Metadata.GetContainingIndexes().Single()); + + modelBuilder.Entity().Metadata.RemoveIndex( + modelBuilder.Entity().Property(e => e.Region).Metadata.GetContainingIndexes().Single()); + + modelBuilder.Entity().Metadata.RemoveIndex( + modelBuilder.Entity().Property(e => e.OrderDate).Metadata.GetContainingIndexes().Single()); + + modelBuilder.Entity().Metadata.RemoveIndex( + modelBuilder.Entity().Property(e => e.ProductName).Metadata.GetContainingIndexes().Single()); } } diff --git a/test/EFCore.Cosmos.Tests/Infrastructure/CosmosModelValidatorTest.cs b/test/EFCore.Cosmos.Tests/Infrastructure/CosmosModelValidatorTest.cs index 72a3f2c2491..0feeb9a8184 100644 --- a/test/EFCore.Cosmos.Tests/Infrastructure/CosmosModelValidatorTest.cs +++ b/test/EFCore.Cosmos.Tests/Infrastructure/CosmosModelValidatorTest.cs @@ -348,6 +348,19 @@ public virtual void Detects_conflicting_containing_property() VerifyError(CosmosStrings.ContainerContainingPropertyConflict(nameof(Order), "Orders", "Prop"), modelBuilder); } + [ConditionalFact] + public virtual void Detects_index() + { + var modelBuilder = CreateConventionModelBuilder(); + modelBuilder.Entity( + b => + { + b.HasIndex(e => new { e.Name, e.OtherName }); + }); + + VerifyError(CosmosStrings.IndexesExist(nameof(Customer), "Name,OtherName"), modelBuilder); + } + [ConditionalFact] public virtual void Detects_missing_discriminator() { diff --git a/test/EFCore.InMemory.FunctionalTests/DataAnnotationInMemoryTest.cs b/test/EFCore.InMemory.FunctionalTests/DataAnnotationInMemoryTest.cs index 4e1e5e50f90..145801b31a7 100644 --- a/test/EFCore.InMemory.FunctionalTests/DataAnnotationInMemoryTest.cs +++ b/test/EFCore.InMemory.FunctionalTests/DataAnnotationInMemoryTest.cs @@ -9,6 +9,9 @@ public class DataAnnotationInMemoryTest(DataAnnotationInMemoryTest.DataAnnotatio protected override TestHelpers TestHelpers => InMemoryTestHelpers.Instance; + protected override bool HasForeignKeyIndexes + => false; + public override Task ConcurrencyCheckAttribute_throws_if_value_in_database_changed() { using var context = CreateContext(); diff --git a/test/EFCore.InMemory.FunctionalTests/ModelBuilding/InMemoryModelBuilderTest.cs b/test/EFCore.InMemory.FunctionalTests/ModelBuilding/InMemoryModelBuilderTest.cs index f7121d01d47..b3708b71b12 100644 --- a/test/EFCore.InMemory.FunctionalTests/ModelBuilding/InMemoryModelBuilderTest.cs +++ b/test/EFCore.InMemory.FunctionalTests/ModelBuilding/InMemoryModelBuilderTest.cs @@ -27,5 +27,8 @@ public abstract class InMemoryOwnedTypes(InMemoryModelBuilderFixture fixture) : public class InMemoryModelBuilderFixture : ModelBuilderFixtureBase { public override TestHelpers TestHelpers => InMemoryTestHelpers.Instance; + + public override bool ForeignKeysHaveIndexes + => false; } } diff --git a/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/ComplexTypes/PrincipalBaseEntityType.cs b/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/ComplexTypes/PrincipalBaseEntityType.cs index 530bc77edc9..b0fc45cfa5c 100644 --- a/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/ComplexTypes/PrincipalBaseEntityType.cs +++ b/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/ComplexTypes/PrincipalBaseEntityType.cs @@ -38,7 +38,6 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas complexPropertyCount: 1, navigationCount: 1, foreignKeyCount: 1, - unnamedIndexCount: 1, keyCount: 1); var id = runtimeEntityType.AddProperty( @@ -856,9 +855,6 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas new[] { id }); runtimeEntityType.SetPrimaryKey(key); - var index = runtimeEntityType.AddIndex( - new[] { principalBaseId }); - return runtimeEntityType; } diff --git a/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/Lazy_loading_manual/LazyProxiesEntity4EntityType.cs b/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/Lazy_loading_manual/LazyProxiesEntity4EntityType.cs index 68c7b57f3c3..59c1c09f817 100644 --- a/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/Lazy_loading_manual/LazyProxiesEntity4EntityType.cs +++ b/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/Lazy_loading_manual/LazyProxiesEntity4EntityType.cs @@ -32,7 +32,6 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas navigationCount: 1, servicePropertyCount: 1, foreignKeyCount: 1, - unnamedIndexCount: 1, keyCount: 1); var id = runtimeEntityType.AddProperty( @@ -217,9 +216,6 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas new[] { id }); runtimeEntityType.SetPrimaryKey(key); - var index = runtimeEntityType.AddIndex( - new[] { referenceNavigationId }); - return runtimeEntityType; } diff --git a/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/Lazy_loading_proxies/LazyProxiesEntity1EntityType.cs b/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/Lazy_loading_proxies/LazyProxiesEntity1EntityType.cs index 2527c6ffd4d..048832212cc 100644 --- a/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/Lazy_loading_proxies/LazyProxiesEntity1EntityType.cs +++ b/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/Lazy_loading_proxies/LazyProxiesEntity1EntityType.cs @@ -33,7 +33,6 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas navigationCount: 1, servicePropertyCount: 1, foreignKeyCount: 1, - unnamedIndexCount: 1, keyCount: 1); var id = runtimeEntityType.AddProperty( @@ -133,9 +132,6 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas new[] { id }); runtimeEntityType.SetPrimaryKey(key); - var index = runtimeEntityType.AddIndex( - new[] { referenceNavigationId }); - return runtimeEntityType; } diff --git a/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/Manual_lazy_loading/LazyPropertyDelegateEntityEntityType.cs b/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/Manual_lazy_loading/LazyPropertyDelegateEntityEntityType.cs index 333a0af2388..f6658fee882 100644 --- a/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/Manual_lazy_loading/LazyPropertyDelegateEntityEntityType.cs +++ b/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/Manual_lazy_loading/LazyPropertyDelegateEntityEntityType.cs @@ -32,7 +32,6 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas navigationCount: 1, servicePropertyCount: 2, foreignKeyCount: 1, - unnamedIndexCount: 1, keyCount: 1); var id = runtimeEntityType.AddProperty( @@ -153,10 +152,6 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas new[] { id }); runtimeEntityType.SetPrimaryKey(key); - var index = runtimeEntityType.AddIndex( - new[] { lazyConstructorEntityId }, - unique: true); - return runtimeEntityType; } diff --git a/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/Manual_lazy_loading/LazyPropertyEntityEntityType.cs b/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/Manual_lazy_loading/LazyPropertyEntityEntityType.cs index 63f5988f801..b1941dcc06b 100644 --- a/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/Manual_lazy_loading/LazyPropertyEntityEntityType.cs +++ b/test/EFCore.InMemory.FunctionalTests/Scaffolding/Baselines/Manual_lazy_loading/LazyPropertyEntityEntityType.cs @@ -32,7 +32,6 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas navigationCount: 1, servicePropertyCount: 1, foreignKeyCount: 1, - unnamedIndexCount: 1, keyCount: 1); var id = runtimeEntityType.AddProperty( @@ -142,10 +141,6 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas new[] { id }); runtimeEntityType.SetPrimaryKey(key); - var index = runtimeEntityType.AddIndex( - new[] { lazyConstructorEntityId }, - unique: true); - return runtimeEntityType; } diff --git a/test/EFCore.Specification.Tests/DataAnnotationTestBase.cs b/test/EFCore.Specification.Tests/DataAnnotationTestBase.cs index f2eb55466ca..a6561f78f0c 100644 --- a/test/EFCore.Specification.Tests/DataAnnotationTestBase.cs +++ b/test/EFCore.Specification.Tests/DataAnnotationTestBase.cs @@ -22,6 +22,9 @@ protected DataAnnotationTestBase(TFixture fixture) protected TFixture Fixture { get; } + protected virtual bool HasForeignKeyIndexes + => true; + protected DbContext CreateContext() => Fixture.CreateContext(); @@ -1653,17 +1656,25 @@ public virtual void ForeignKeyAttribute_configures_two_self_referencing_relation var fk1 = entityType.GetForeignKeys().Single(fk => fk.Properties.Single().Name == nameof(Comment.ParentCommentID)); Assert.Equal(nameof(Comment.ParentComment), fk1.DependentToPrincipal.Name); Assert.Null(fk1.PrincipalToDependent); - var index1 = entityType.FindIndex(fk1.Properties); - Assert.False(index1.IsUnique); + + if (HasForeignKeyIndexes) + { + var index1 = entityType.FindIndex(fk1.Properties); + Assert.False(index1.IsUnique); + } var fk2 = entityType.GetForeignKeys().Single(fk => fk.Properties.Single().Name == nameof(Comment.ReplyCommentID)); Assert.Equal(nameof(Comment.ReplyComment), fk2.DependentToPrincipal.Name); Assert.Null(fk2.PrincipalToDependent); - var index2 = entityType.FindIndex(fk2.Properties); - Assert.False(index2.IsUnique); + + if (HasForeignKeyIndexes) + { + var index2 = entityType.FindIndex(fk2.Properties); + Assert.False(index2.IsUnique); + } Assert.Equal(2, entityType.GetForeignKeys().Count()); - Assert.Equal(2, entityType.GetIndexes().Count()); + Assert.Equal(HasForeignKeyIndexes ? 2 : 0, entityType.GetIndexes().Count()); } private class Comment diff --git a/test/EFCore.Specification.Tests/ModelBuilding/ModelBuilderTest.Inheritance.cs b/test/EFCore.Specification.Tests/ModelBuilding/ModelBuilderTest.Inheritance.cs index 9da2eb17c75..3fd1a5f1dbd 100644 --- a/test/EFCore.Specification.Tests/ModelBuilding/ModelBuilderTest.Inheritance.cs +++ b/test/EFCore.Specification.Tests/ModelBuilding/ModelBuilderTest.Inheritance.cs @@ -158,8 +158,8 @@ public virtual void Can_set_and_remove_base_type() return true; }); Fixture.TestHelpers.ModelAsserter.AssertEqual( - initialIndexes.Single().Properties, - pickle.GetIndexes().Single().Properties); + initialIndexes.SingleOrDefault()?.Properties ?? Array.Empty(), + pickle.GetIndexes().SingleOrDefault()?.Properties ?? Array.Empty()); Fixture.TestHelpers.ModelAsserter.AssertEqual( initialForeignKeys.Single().Properties, pickle.GetForeignKeys().Single().Properties); @@ -189,8 +189,8 @@ public virtual void Can_set_and_remove_base_type() return true; }); Fixture.TestHelpers.ModelAsserter.AssertEqual( - initialIndexes.Single().Properties, - ingredient.GetIndexes().Single().Properties); + initialIndexes.SingleOrDefault()?.Properties ?? Array.Empty(), + ingredient.GetIndexes().SingleOrDefault()?.Properties ?? Array.Empty()); Fixture.TestHelpers.ModelAsserter.AssertEqual( initialForeignKeys.Single().Properties, ingredient.GetForeignKeys().Single().Properties); @@ -569,6 +569,11 @@ public virtual void Removing_a_key_triggers_fk_discovery_on_derived_types() [ConditionalFact] public virtual void Index_removed_when_covered_by_an_inherited_foreign_key() { + if (!Fixture.ForeignKeysHaveIndexes) + { + return; + } + var modelBuilder = CreateModelBuilder(); modelBuilder.Ignore(); modelBuilder.Ignore(); @@ -653,6 +658,11 @@ public virtual void Index_removed_when_covered_by_an_inherited_foreign_key() [ConditionalFact] public virtual void Index_removed_when_covered_by_an_inherited_index() { + if (!Fixture.ForeignKeysHaveIndexes) + { + return; + } + var modelBuilder = CreateModelBuilder(); modelBuilder.Ignore(); modelBuilder.Ignore(); diff --git a/test/EFCore.Specification.Tests/ModelBuilding/ModelBuilderTest.ManyToOne.cs b/test/EFCore.Specification.Tests/ModelBuilding/ModelBuilderTest.ManyToOne.cs index c15c2b4c762..356674907c6 100644 --- a/test/EFCore.Specification.Tests/ModelBuilding/ModelBuilderTest.ManyToOne.cs +++ b/test/EFCore.Specification.Tests/ModelBuilding/ModelBuilderTest.ManyToOne.cs @@ -44,8 +44,17 @@ public virtual void Finds_existing_navigations_and_uses_associated_FK() Assert.Empty(principalType.GetForeignKeys()); Assert.Same(principalKey, principalType.FindPrimaryKey()); Assert.Same(dependentKey, dependentType.FindPrimaryKey()); - Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); - Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties).IsUnique); + + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); + Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties)!.IsUnique); + } + else + { + Assert.Empty(dependentType.GetIndexes()); + } + Assert.Empty(principalType.GetIndexes()); } @@ -103,8 +112,17 @@ public virtual void Finds_existing_navigations_and_uses_associated_FK_with_field Assert.Empty(principalType.GetForeignKeys()); Assert.Same(principalKey, principalType.FindPrimaryKey()); Assert.Same(dependentKey, dependentType.FindPrimaryKey()); - Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); - Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties).IsUnique); + + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); + Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties)!.IsUnique); + } + else + { + Assert.Empty(dependentType.GetIndexes()); + } + Assert.Empty(principalType.GetIndexes()); } @@ -137,8 +155,17 @@ public virtual void Finds_existing_navigation_to_principal_and_uses_associated_F Assert.Empty(principalType.GetForeignKeys()); Assert.Same(principalKey, principalType.FindPrimaryKey()); Assert.Same(dependentKey, dependentType.FindPrimaryKey()); - Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); - Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties).IsUnique); + + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); + Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties)!.IsUnique); + } + else + { + Assert.Empty(dependentType.GetIndexes()); + } + Assert.Empty(principalType.GetIndexes()); } @@ -174,8 +201,17 @@ public virtual void Finds_existing_navigation_to_dependent_and_uses_associated_F Assert.Empty(principalType.GetForeignKeys()); Assert.Same(principalKey, principalType.FindPrimaryKey()); Assert.Same(dependentKey, dependentType.FindPrimaryKey()); - Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); - Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties).IsUnique); + + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); + Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties)!.IsUnique); + } + else + { + Assert.Empty(dependentType.GetIndexes()); + } + Assert.Empty(principalType.GetIndexes()); } @@ -209,8 +245,17 @@ public virtual void Creates_both_navigations_and_does_not_use_existing_FK() Assert.Same(fk, principalType.GetNavigations().Single().ForeignKey); Assert.Same(principalKey, principalType.FindPrimaryKey()); Assert.Same(dependentKey, dependentType.FindPrimaryKey()); - Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); - Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties).IsUnique); + + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); + Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties)!.IsUnique); + } + else + { + Assert.Empty(dependentType.GetIndexes()); + } + Assert.Empty(principalType.GetIndexes()); } @@ -248,8 +293,17 @@ public virtual void Creates_both_navigations_and_creates_new_FK() Assert.Empty(principalType.GetForeignKeys()); Assert.Same(principalKey, principalType.FindPrimaryKey()); Assert.Same(dependentKey, dependentType.FindPrimaryKey()); - Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); - Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties).IsUnique); + + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); + Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties)!.IsUnique); + } + else + { + Assert.Empty(dependentType.GetIndexes()); + } + Assert.Empty(principalType.GetIndexes()); } @@ -281,8 +335,17 @@ public virtual void Creates_relationship_with_navigation_to_principal() Assert.Same(principalKey, principalType.FindPrimaryKey()); Assert.Same(dependentKey, dependentType.FindPrimaryKey()); Assert.NotNull(dependentType.FindForeignKeys(fkProperty).SingleOrDefault()); - Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); - Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties).IsUnique); + + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); + Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties)!.IsUnique); + } + else + { + Assert.Empty(dependentType.GetIndexes()); + } + Assert.Empty(principalType.GetIndexes()); } @@ -313,8 +376,17 @@ public virtual void Creates_relationship_with_navigation_to_dependent() Assert.Same(principalKey, principalType.FindPrimaryKey()); Assert.Same(dependentKey, dependentType.FindPrimaryKey()); Assert.NotNull(dependentType.FindForeignKeys(fkProperty).SingleOrDefault()); - Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); - Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties).IsUnique); + + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); + Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties)!.IsUnique); + } + else + { + Assert.Empty(dependentType.GetIndexes()); + } + Assert.Empty(principalType.GetIndexes()); } @@ -350,8 +422,17 @@ public virtual void Creates_relationship_with_no_navigations() Assert.Empty(principalType.GetForeignKeys()); Assert.Same(principalKey, principalType.FindPrimaryKey()); Assert.Same(dependentKey, dependentType.FindPrimaryKey()); - Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); - Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties).IsUnique); + + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); + Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties)!.IsUnique); + } + else + { + Assert.Empty(dependentType.GetIndexes()); + } + Assert.Empty(principalType.GetIndexes()); } @@ -391,8 +472,17 @@ public virtual void Creates_both_navigations_and_uses_specified_FK_even_if_found Assert.Empty(principalType.GetForeignKeys()); Assert.Same(principalKey, principalType.FindPrimaryKey()); Assert.Same(dependentKey, dependentType.FindPrimaryKey()); - Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); - Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties).IsUnique); + + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); + Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties)!.IsUnique); + } + else + { + Assert.Empty(dependentType.GetIndexes()); + } + Assert.Empty(principalType.GetIndexes()); } @@ -428,8 +518,17 @@ public virtual void Creates_both_navigations_with_existing_FK_not_found_by_conve Assert.Empty(principalType.GetForeignKeys()); Assert.Same(principalKey, principalType.FindPrimaryKey()); Assert.Same(dependentKey, dependentType.FindPrimaryKey()); - Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); - Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties).IsUnique); + + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); + Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties)!.IsUnique); + } + else + { + Assert.Empty(dependentType.GetIndexes()); + } + Assert.Empty(principalType.GetIndexes()); } @@ -466,8 +565,17 @@ public virtual void Creates_both_navigations_and_creates_FK_specified() Assert.Empty(principalType.GetForeignKeys()); Assert.Same(principalKey, principalType.FindPrimaryKey()); Assert.Same(dependentKey, dependentType.FindPrimaryKey()); - Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); - Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties).IsUnique); + + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); + Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties)!.IsUnique); + } + else + { + Assert.Empty(dependentType.GetIndexes()); + } + Assert.Empty(principalType.GetIndexes()); } @@ -500,8 +608,17 @@ public virtual void Creates_specified_FK_with_navigation_to_principal() Assert.NotSame(fk, principalType.GetNavigations().Single().ForeignKey); Assert.Same(principalKey, principalType.FindPrimaryKey()); Assert.Same(dependentKey, dependentType.FindPrimaryKey()); - Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); - Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties).IsUnique); + + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); + Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties)!.IsUnique); + } + else + { + Assert.Empty(dependentType.GetIndexes()); + } + Assert.Empty(principalType.GetIndexes()); } @@ -536,8 +653,17 @@ public virtual void Creates_specified_FK_with_navigation_to_dependent() Assert.NotSame(fk, dependentType.GetNavigations().Single().ForeignKey); Assert.Same(principalKey, principalType.FindPrimaryKey()); Assert.Same(dependentKey, dependentType.FindPrimaryKey()); - Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); - Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties).IsUnique); + + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); + Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties)!.IsUnique); + } + else + { + Assert.Empty(dependentType.GetIndexes()); + } + Assert.Empty(principalType.GetIndexes()); } @@ -573,8 +699,17 @@ public virtual void Creates_relationship_with_no_navigations_and_specified_FK() Assert.Empty(principalType.GetForeignKeys()); Assert.Same(principalKey, principalType.FindPrimaryKey()); Assert.Same(dependentKey, dependentType.FindPrimaryKey()); - Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); - Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties).IsUnique); + + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); + Assert.False(fk!.DeclaringEntityType.FindIndex(fk.Properties)!.IsUnique); + } + else + { + Assert.Empty(dependentType.GetIndexes()); + } + Assert.Empty(principalType.GetIndexes()); } @@ -610,8 +745,17 @@ public virtual void Creates_both_navigations_and_creates_shadow_FK() Assert.Same(fk, dependentType.GetNavigations().Single().ForeignKey); Assert.Same(fk, principalType.GetNavigations().Single().ForeignKey); Assert.Empty(principalType.GetForeignKeys()); - Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); - Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties).IsUnique); + + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); + Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties)!.IsUnique); + } + else + { + Assert.Empty(dependentType.GetIndexes()); + } + Assert.Empty(principalType.GetIndexes()); } @@ -644,8 +788,17 @@ public virtual void Creates_shadow_FK_with_navigation_to_principal() Assert.Equal(nameof(Pickle.BigMak), dependentType.GetNavigations().Single().Name); Assert.Same(fk, dependentType.GetNavigations().Single().ForeignKey); Assert.NotSame(fk, principalType.GetNavigations().Single().ForeignKey); - Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); - Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties).IsUnique); + + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); + Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties)!.IsUnique); + } + else + { + Assert.Empty(dependentType.GetIndexes()); + } + Assert.Empty(principalType.GetIndexes()); } @@ -678,8 +831,17 @@ public virtual void Creates_shadow_FK_with_navigation_to_dependent() Assert.Equal(nameof(BigMak.Pickles), fk.PrincipalToDependent.Name); Assert.Null(fk.DependentToPrincipal); Assert.NotSame(fk, dependentType.GetNavigations().Single().ForeignKey); - Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); - Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties).IsUnique); + + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); + Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties)!.IsUnique); + } + else + { + Assert.Empty(dependentType.GetIndexes()); + } + Assert.Empty(principalType.GetIndexes()); } @@ -714,8 +876,17 @@ public virtual void Creates_shadow_FK_with_no_navigations_with() Assert.Empty(dependentType.GetNavigations().Where(nav => nav.ForeignKey != fk)); Assert.Empty(principalType.GetNavigations().Where(nav => nav.ForeignKey != fk)); Assert.Empty(principalType.GetForeignKeys()); - Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); - Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties).IsUnique); + + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); + Assert.False(fk!.DeclaringEntityType.FindIndex(fk.Properties)!.IsUnique); + } + else + { + Assert.Empty(dependentType.GetIndexes()); + } + Assert.Empty(principalType.GetIndexes()); } @@ -748,8 +919,17 @@ public virtual void Creates_both_navigations_and_matches_shadow_FK_by_convention Assert.Same(fk, dependentType.GetNavigations().Single().ForeignKey); Assert.Same(fk, principalType.GetNavigations().Single().ForeignKey); Assert.Empty(principalType.GetForeignKeys()); - Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); - Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties).IsUnique); + + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); + Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties)!.IsUnique); + } + else + { + Assert.Empty(dependentType.GetIndexes()); + } + Assert.Empty(principalType.GetIndexes()); } @@ -784,8 +964,17 @@ public virtual void Creates_both_navigations_and_overrides_existing_FK_if_unique Assert.Same(fk, dependentType.GetNavigations().Single().ForeignKey); Assert.Same(fk, principalType.GetNavigations().Single().ForeignKey); Assert.Empty(principalType.GetForeignKeys()); - Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); - Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties).IsUnique); + + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); + Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties)!.IsUnique); + } + else + { + Assert.Empty(dependentType.GetIndexes()); + } + Assert.Empty(principalType.GetIndexes()); } @@ -839,8 +1028,17 @@ public virtual void Can_use_explicitly_specified_PK() Assert.Same(fk, dependentType.GetNavigations().Single().ForeignKey); Assert.Same(fk, principalType.GetNavigations().Single().ForeignKey); Assert.Empty(principalType.GetForeignKeys()); - Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); - Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties).IsUnique); + + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); + Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties)!.IsUnique); + } + else + { + Assert.Empty(dependentType.GetIndexes()); + } + Assert.Empty(principalType.GetIndexes()); } @@ -892,8 +1090,16 @@ public virtual void Can_use_non_PK_principal() expectedDependentProperties.Add(fk.Properties.Single()); AssertEqual(expectedDependentProperties, dependentType.GetProperties()); - Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); - Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties).IsUnique); + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); + Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties)!.IsUnique); + } + else + { + Assert.Empty(dependentType.GetIndexes()); + } + Assert.Empty(principalType.GetIndexes()); } @@ -934,8 +1140,17 @@ public virtual void Can_have_both_convention_properties_specified() Assert.Same(fk, dependentType.GetNavigations().Single().ForeignKey); Assert.Same(fk, principalType.GetNavigations().Single().ForeignKey); Assert.Empty(principalType.GetForeignKeys()); - Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); - Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties).IsUnique); + + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); + Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties)!.IsUnique); + } + else + { + Assert.Empty(dependentType.GetIndexes()); + } + Assert.Empty(principalType.GetIndexes()); } @@ -976,8 +1191,17 @@ public virtual void Can_have_both_convention_properties_specified_in_any_order() Assert.Same(fk, dependentType.GetNavigations().Single().ForeignKey); Assert.Same(fk, principalType.GetNavigations().Single().ForeignKey); Assert.Empty(principalType.GetForeignKeys()); - Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); - Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties).IsUnique); + + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); + Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties)!.IsUnique); + } + else + { + Assert.Empty(dependentType.GetIndexes()); + } + Assert.Empty(principalType.GetIndexes()); } @@ -1023,8 +1247,16 @@ public virtual void Can_have_FK_by_convention_specified_with_explicit_principal_ AssertEqual(expectedPrincipalProperties, principalType.GetProperties()); AssertEqual(expectedDependentProperties, dependentType.GetProperties()); - Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); - Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties).IsUnique); + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); + Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties)!.IsUnique); + } + else + { + Assert.Empty(dependentType.GetIndexes()); + } + Assert.Empty(principalType.GetIndexes()); } @@ -1070,8 +1302,16 @@ public virtual void Can_have_FK_by_convention_specified_with_explicit_principal_ AssertEqual(expectedPrincipalProperties, principalType.GetProperties()); AssertEqual(expectedDependentProperties, dependentType.GetProperties()); - Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); - Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties).IsUnique); + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); + Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties)!.IsUnique); + } + else + { + Assert.Empty(dependentType.GetIndexes()); + } + Assert.Empty(principalType.GetIndexes()); } @@ -1117,8 +1357,16 @@ public virtual void Can_have_principal_key_by_convention_specified_with_explicit Assert.Same(principalKey, principalType.FindPrimaryKey()); Assert.Same(dependentKey, dependentType.FindPrimaryKey()); - Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); - Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties).IsUnique); + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); + Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties)!.IsUnique); + } + else + { + Assert.Empty(dependentType.GetIndexes()); + } + Assert.Empty(principalType.GetIndexes()); } @@ -1164,8 +1412,16 @@ public virtual void Can_have_principal_key_by_convention_specified_with_explicit Assert.Same(principalKey, principalType.FindPrimaryKey()); Assert.Same(dependentKey, dependentType.FindPrimaryKey()); - Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); - Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties).IsUnique); + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); + Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties)!.IsUnique); + } + else + { + Assert.Empty(dependentType.GetIndexes()); + } + Assert.Empty(principalType.GetIndexes()); } @@ -1246,8 +1502,17 @@ public virtual void Creates_both_navigations_and_finds_existing_composite_FK() Assert.Empty(principalType.GetForeignKeys()); Assert.Same(principalKey, principalType.FindPrimaryKey()); Assert.Same(dependentKey, dependentType.FindPrimaryKey()); - Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); - Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties).IsUnique); + + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); + Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties)!.IsUnique); + } + else + { + Assert.Empty(dependentType.GetIndexes()); + } + Assert.Empty(principalType.GetIndexes()); } @@ -1289,8 +1554,17 @@ public virtual void Creates_both_navigations_and_creates_composite_FK_specified( Assert.Empty(principalType.GetForeignKeys()); Assert.Same(principalKey, principalType.FindPrimaryKey()); Assert.Same(dependentKey, dependentType.FindPrimaryKey()); - Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); - Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties).IsUnique); + + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); + Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties)!.IsUnique); + } + else + { + Assert.Empty(dependentType.GetIndexes()); + } + Assert.Empty(principalType.GetIndexes()); } @@ -1345,8 +1619,16 @@ public virtual void Can_use_alternate_composite_key() Assert.Same(principalKey, principalType.FindPrimaryKey()); Assert.Same(dependentKey, dependentType.FindPrimaryKey()); - Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); - Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties).IsUnique); + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); + Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties)!.IsUnique); + } + else + { + Assert.Empty(dependentType.GetIndexes()); + } + Assert.Empty(principalType.GetIndexes()); } @@ -1401,8 +1683,16 @@ public virtual void Can_use_alternate_composite_key_in_any_order() Assert.Same(principalKey, principalType.FindPrimaryKey()); Assert.Same(dependentKey, dependentType.FindPrimaryKey()); - Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); - Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties).IsUnique); + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); + Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties)!.IsUnique); + } + else + { + Assert.Empty(dependentType.GetIndexes()); + } + Assert.Empty(principalType.GetIndexes()); } @@ -1442,8 +1732,17 @@ public virtual void Creates_specified_composite_FK_with_navigation_to_principal( Assert.NotSame(fk, principalType.GetNavigations().Single().ForeignKey); Assert.Same(principalKey, principalType.FindPrimaryKey()); Assert.Same(dependentKey, dependentType.FindPrimaryKey()); - Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); - Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties).IsUnique); + + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); + Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties)!.IsUnique); + } + else + { + Assert.Empty(dependentType.GetIndexes()); + } + Assert.Empty(principalType.GetIndexes()); } @@ -1483,8 +1782,17 @@ public virtual void Creates_specified_composite_FK_with_navigation_to_dependent( Assert.NotSame(fk, dependentType.GetNavigations().Single().ForeignKey); Assert.Same(principalKey, principalType.FindPrimaryKey()); Assert.Same(dependentKey, dependentType.FindPrimaryKey()); - Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); - Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties).IsUnique); + + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); + Assert.False(fk!.DeclaringEntityType.FindIndex(fk.Properties)!.IsUnique); + } + else + { + Assert.Empty(dependentType.GetIndexes()); + } + Assert.Empty(principalType.GetIndexes()); } @@ -1531,8 +1839,17 @@ public virtual void Creates_relationship_with_no_navigations_and_specified_compo Assert.Empty(principalType.GetForeignKeys()); Assert.Same(principalKey, principalType.FindPrimaryKey()); Assert.Same(dependentKey, dependentType.FindPrimaryKey()); - Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); - Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties).IsUnique); + + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); + Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties)!.IsUnique); + } + else + { + Assert.Empty(dependentType.GetIndexes()); + } + Assert.Empty(principalType.GetIndexes()); } @@ -1572,10 +1889,19 @@ public virtual void Creates_relationship_on_existing_FK_is_using_different_princ var fk = dependentType.GetForeignKeys().Single(foreignKey => foreignKey != existingFk); Assert.NotSame(principalKey, fk.PrincipalKey); - Assert.Equal(principalType.GetForeignKeys().Count(), principalType.GetIndexes().Count()); - Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); - Assert.True(existingFk.DeclaringEntityType.FindIndex(existingFk.Properties).IsUnique); - Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties).IsUnique); + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Equal(principalType.GetForeignKeys().Count(), principalType.GetIndexes().Count()); + Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); + Assert.True(existingFk.DeclaringEntityType.FindIndex(existingFk.Properties)!.IsUnique); + Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties)!.IsUnique); + } + else + { + Assert.Empty(principalType.GetIndexes()); + Assert.Empty(dependentType.GetIndexes()); + } + Assert.Equal( CoreStrings.AmbiguousOneToOneRelationship( @@ -1621,8 +1947,16 @@ public virtual void Creates_relationship_on_existing_FK_is_using_different_princ var fk = dependentType.GetForeignKeys().Single(foreignKey => foreignKey != existingFk); Assert.NotSame(principalKey, fk.PrincipalKey); Assert.Empty(principalType.GetIndexes()); - Assert.Single(dependentType.GetIndexes()); - Assert.True(fk.DeclaringEntityType.FindIndex(fk.Properties).IsUnique); + + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Single(dependentType.GetIndexes()); + Assert.True(fk.DeclaringEntityType.FindIndex(fk.Properties)!.IsUnique); + } + else + { + Assert.Empty(dependentType.GetIndexes()); + } } [ConditionalFact] diff --git a/test/EFCore.Specification.Tests/ModelBuilding/ModelBuilderTest.NonRelationship.cs b/test/EFCore.Specification.Tests/ModelBuilding/ModelBuilderTest.NonRelationship.cs index f58356a4d58..533b9056a2b 100644 --- a/test/EFCore.Specification.Tests/ModelBuilding/ModelBuilderTest.NonRelationship.cs +++ b/test/EFCore.Specification.Tests/ModelBuilding/ModelBuilderTest.NonRelationship.cs @@ -7,7 +7,6 @@ using System.Dynamic; using Microsoft.EntityFrameworkCore.ChangeTracking.Internal; using Microsoft.EntityFrameworkCore.Metadata.Internal; -using Microsoft.EntityFrameworkCore.Scaffolding; using Microsoft.EntityFrameworkCore.TestUtilities.Xunit; // ReSharper disable InconsistentNaming diff --git a/test/EFCore.Specification.Tests/ModelBuilding/ModelBuilderTest.OneToMany.cs b/test/EFCore.Specification.Tests/ModelBuilding/ModelBuilderTest.OneToMany.cs index c4e809706c7..ff7d6d6e3ca 100644 --- a/test/EFCore.Specification.Tests/ModelBuilding/ModelBuilderTest.OneToMany.cs +++ b/test/EFCore.Specification.Tests/ModelBuilding/ModelBuilderTest.OneToMany.cs @@ -47,8 +47,17 @@ public virtual void Finds_existing_navigations_and_uses_associated_FK() Assert.Empty(principalType.GetForeignKeys()); Assert.Same(principalKey, principalType.FindPrimaryKey()); Assert.Same(dependentKey, dependentType.FindPrimaryKey()); - Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); - Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties).IsUnique); + + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); + Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties)!.IsUnique); + } + else + { + Assert.Empty(dependentType.GetIndexes()); + } + Assert.Empty(principalType.GetIndexes()); } @@ -106,8 +115,17 @@ public virtual void Finds_existing_navigations_and_uses_associated_FK_with_field Assert.Empty(principalType.GetForeignKeys()); Assert.Same(principalKey, principalType.FindPrimaryKey()); Assert.Same(dependentKey, dependentType.FindPrimaryKey()); - Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); - Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties).IsUnique); + + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); + Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties)!.IsUnique); + } + else + { + Assert.Empty(dependentType.GetIndexes()); + } + Assert.Empty(principalType.GetIndexes()); } @@ -140,8 +158,17 @@ public virtual void Finds_existing_navigation_to_principal_and_uses_associated_F Assert.Empty(principalType.GetForeignKeys()); Assert.Same(principalKey, principalType.FindPrimaryKey()); Assert.Same(dependentKey, dependentType.FindPrimaryKey()); - Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); - Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties).IsUnique); + + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); + Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties)!.IsUnique); + } + else + { + Assert.Empty(dependentType.GetIndexes()); + } + Assert.Empty(principalType.GetIndexes()); } @@ -175,8 +202,17 @@ public virtual void Finds_existing_navigation_to_dependent_and_uses_associated_F Assert.Equal(nameof(Customer.Orders), newFk.PrincipalToDependent.Name); Assert.Same(principalKey, principalType.FindPrimaryKey()); Assert.Same(dependentKey, dependentType.FindPrimaryKey()); - Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); - Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties).IsUnique); + + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); + Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties)!.IsUnique); + } + else + { + Assert.Empty(dependentType.GetIndexes()); + } + Assert.Empty(principalType.GetIndexes()); } @@ -213,8 +249,17 @@ public virtual void Creates_both_navigations_and_uses_existing_FK() Assert.Empty(principalType.GetForeignKeys()); Assert.Same(principalKey, principalType.FindPrimaryKey()); Assert.Same(dependentKey, dependentType.FindPrimaryKey()); - Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); - Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties).IsUnique); + + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); + Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties)!.IsUnique); + } + else + { + Assert.Empty(dependentType.GetIndexes()); + } + Assert.Empty(principalType.GetIndexes()); } @@ -252,8 +297,17 @@ public virtual void Creates_relationship_with_both_navigations() Assert.Empty(principalType.GetForeignKeys()); Assert.Same(principalKey, principalType.FindPrimaryKey()); Assert.Same(dependentKey, dependentType.FindPrimaryKey()); - Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); - Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties).IsUnique); + + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); + Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties)!.IsUnique); + } + else + { + Assert.Empty(dependentType.GetIndexes()); + } + Assert.Empty(principalType.GetIndexes()); } @@ -283,8 +337,17 @@ public virtual void Creates_relationship_with_navigation_to_dependent() Assert.Same(principalKey, principalType.FindPrimaryKey()); Assert.Same(dependentKey, dependentType.FindPrimaryKey()); Assert.NotNull(dependentType.FindForeignKeys(fkProperty).SingleOrDefault()); - Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); - Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties).IsUnique); + + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); + Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties)!.IsUnique); + } + else + { + Assert.Empty(dependentType.GetIndexes()); + } + Assert.Empty(principalType.GetIndexes()); } @@ -315,8 +378,17 @@ public virtual void Creates_relationship_with_navigation_to_principal() Assert.Same(principalKey, principalType.FindPrimaryKey()); Assert.Same(dependentKey, dependentType.FindPrimaryKey()); Assert.NotNull(dependentType.FindForeignKeys(fkProperty).SingleOrDefault()); - Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); - Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties).IsUnique); + + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); + Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties)!.IsUnique); + } + else + { + Assert.Empty(dependentType.GetIndexes()); + } + Assert.Empty(principalType.GetIndexes()); } @@ -353,8 +425,17 @@ public virtual void Creates_relationship_with_no_navigations() Assert.Empty(principalType.GetForeignKeys()); Assert.Same(principalKey, principalType.FindPrimaryKey()); Assert.Same(dependentKey, dependentType.FindPrimaryKey()); - Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); - Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties).IsUnique); + + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); + Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties)!.IsUnique); + } + else + { + Assert.Empty(dependentType.GetIndexes()); + } + Assert.Empty(principalType.GetIndexes()); } @@ -394,8 +475,17 @@ public virtual void Creates_both_navigations_and_uses_specified_FK_even_if_found Assert.Empty(principalType.GetForeignKeys()); Assert.Same(principalKey, principalType.FindPrimaryKey()); Assert.Same(dependentKey, dependentType.FindPrimaryKey()); - Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); - Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties).IsUnique); + + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); + Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties)!.IsUnique); + } + else + { + Assert.Empty(dependentType.GetIndexes()); + } + Assert.Empty(principalType.GetIndexes()); } @@ -432,8 +522,17 @@ public virtual void Creates_both_navigations_and_uses_existing_FK_not_found_by_c Assert.Empty(principalType.GetForeignKeys()); Assert.Same(principalKey, principalType.FindPrimaryKey()); Assert.Same(dependentKey, dependentType.FindPrimaryKey()); - Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); - Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties).IsUnique); + + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); + Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties)!.IsUnique); + } + else + { + Assert.Empty(dependentType.GetIndexes()); + } + Assert.Empty(principalType.GetIndexes()); } @@ -470,8 +569,17 @@ public virtual void Creates_both_navigations_and_creates_FK_specified() Assert.Empty(principalType.GetForeignKeys()); Assert.Same(principalKey, principalType.FindPrimaryKey()); Assert.Same(dependentKey, dependentType.FindPrimaryKey()); - Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); - Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties).IsUnique); + + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); + Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties)!.IsUnique); + } + else + { + Assert.Empty(dependentType.GetIndexes()); + } + Assert.Empty(principalType.GetIndexes()); } @@ -505,8 +613,17 @@ public virtual void Creates_specified_FK_with_navigation_to_dependent() Assert.Null(fk.DependentToPrincipal); Assert.Same(principalKey, principalType.FindPrimaryKey()); Assert.Same(dependentKey, dependentType.FindPrimaryKey()); - Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); - Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties).IsUnique); + + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); + Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties)!.IsUnique); + } + else + { + Assert.Empty(dependentType.GetIndexes()); + } + Assert.Empty(principalType.GetIndexes()); } @@ -538,8 +655,17 @@ public virtual void Creates_specified_FK_with_navigation_to_principal() Assert.NotSame(fk, principalType.GetNavigations().Single().ForeignKey); Assert.Same(principalKey, principalType.FindPrimaryKey()); Assert.Same(dependentKey, dependentType.FindPrimaryKey()); - Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); - Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties).IsUnique); + + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); + Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties)!.IsUnique); + } + else + { + Assert.Empty(dependentType.GetIndexes()); + } + Assert.Empty(principalType.GetIndexes()); } @@ -575,8 +701,17 @@ public virtual void Creates_relationship_with_no_navigations_and_specified_FK() Assert.Empty(principalType.GetForeignKeys()); Assert.Same(principalKey, principalType.FindPrimaryKey()); Assert.Same(dependentKey, dependentType.FindPrimaryKey()); - Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); - Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties).IsUnique); + + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); + Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties)!.IsUnique); + } + else + { + Assert.Empty(dependentType.GetIndexes()); + } + Assert.Empty(principalType.GetIndexes()); } @@ -614,8 +749,17 @@ public virtual void Creates_both_navigations_and_creates_shadow_FK() Assert.Empty(principalType.GetForeignKeys()); Assert.Same(principalKey, principalType.FindPrimaryKey()); Assert.Same(dependentKey, dependentType.FindPrimaryKey()); - Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); - Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties).IsUnique); + + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); + Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties)!.IsUnique); + } + else + { + Assert.Empty(dependentType.GetIndexes()); + } + Assert.Empty(principalType.GetIndexes()); } @@ -649,8 +793,17 @@ public virtual void Creates_shadow_FK_with_navigation_to_dependent() Assert.Null(fk.DependentToPrincipal); Assert.Same(principalKey, principalType.FindPrimaryKey()); Assert.Same(dependentKey, dependentType.FindPrimaryKey()); - Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); - Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties).IsUnique); + + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); + Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties)!.IsUnique); + } + else + { + Assert.Empty(dependentType.GetIndexes()); + } + Assert.Empty(principalType.GetIndexes()); } @@ -685,8 +838,17 @@ public virtual void Creates_shadow_FK_with_navigation_to_principal() Assert.NotSame(fk, principalType.GetNavigations().Single().ForeignKey); Assert.Same(principalKey, principalType.FindPrimaryKey()); Assert.Same(dependentKey, dependentType.FindPrimaryKey()); - Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); - Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties).IsUnique); + + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); + Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties)!.IsUnique); + } + else + { + Assert.Empty(dependentType.GetIndexes()); + } + Assert.Empty(principalType.GetIndexes()); } @@ -722,8 +884,17 @@ public virtual void Creates_shadow_FK_with_no_navigation() Assert.Empty(principalType.GetNavigations().Where(nav => nav.ForeignKey != existingFk)); Assert.Empty(principalType.GetForeignKeys()); Assert.Same(principalKey, principalType.FindPrimaryKey()); - Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); - Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties).IsUnique); + + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); + Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties)!.IsUnique); + } + else + { + Assert.Empty(dependentType.GetIndexes()); + } + Assert.Empty(principalType.GetIndexes()); } @@ -758,8 +929,17 @@ public virtual void Creates_both_navigations_and_matches_shadow_FK_property_by_c Assert.Empty(principalType.GetForeignKeys()); Assert.Same(principalKey, principalType.FindPrimaryKey()); Assert.Same(dependentKey, dependentType.FindPrimaryKey()); - Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); - Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties).IsUnique); + + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); + Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties)!.IsUnique); + } + else + { + Assert.Empty(dependentType.GetIndexes()); + } + Assert.Empty(principalType.GetIndexes()); } @@ -798,8 +978,17 @@ public virtual void Creates_both_navigations_and_overrides_existing_FK_when_uniq Assert.Empty(principalType.GetForeignKeys()); Assert.Same(principalKey, principalType.FindPrimaryKey()); Assert.Same(dependentKey, dependentType.FindPrimaryKey()); - Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); - Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties).IsUnique); + + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); + Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties)!.IsUnique); + } + else + { + Assert.Empty(dependentType.GetIndexes()); + } + Assert.Empty(principalType.GetIndexes()); } @@ -856,8 +1045,17 @@ public virtual void Can_use_explicitly_specified_PK() Assert.Empty(principalType.GetForeignKeys()); Assert.Same(principalKey, principalType.FindPrimaryKey()); Assert.Same(dependentKey, dependentType.FindPrimaryKey()); - Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); - Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties).IsUnique); + + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); + Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties)!.IsUnique); + } + else + { + Assert.Empty(dependentType.GetIndexes()); + } + Assert.Empty(principalType.GetIndexes()); } @@ -904,8 +1102,17 @@ public virtual void Can_use_non_PK_principal() AssertEqual(expectedPrincipalProperties, principalType.GetProperties()); expectedDependentProperties.Add(fk.Properties.Single()); AssertEqual(expectedDependentProperties, dependentType.GetProperties()); - Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); - Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties).IsUnique); + + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); + Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties)!.IsUnique); + } + else + { + Assert.Empty(dependentType.GetIndexes()); + } + Assert.Empty(principalType.GetIndexes()); } @@ -1006,8 +1213,17 @@ public virtual void Can_have_both_convention_properties_specified() Assert.Empty(principalType.GetForeignKeys()); Assert.Same(principalKey, principalType.FindPrimaryKey()); Assert.Same(dependentKey, dependentType.FindPrimaryKey()); - Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); - Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties).IsUnique); + + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); + Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties)!.IsUnique); + } + else + { + Assert.Empty(dependentType.GetIndexes()); + } + Assert.Empty(principalType.GetIndexes()); } @@ -1050,8 +1266,17 @@ public virtual void Can_have_both_convention_properties_specified_in_any_order() Assert.Empty(principalType.GetForeignKeys()); Assert.Same(principalKey, principalType.FindPrimaryKey()); Assert.Same(dependentKey, dependentType.FindPrimaryKey()); - Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); - Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties).IsUnique); + + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); + Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties)!.IsUnique); + } + else + { + Assert.Empty(dependentType.GetIndexes()); + } + Assert.Empty(principalType.GetIndexes()); } @@ -1097,8 +1322,16 @@ public virtual void Can_have_FK_by_convention_specified_with_explicit_principal_ AssertEqual(expectedPrincipalProperties, principalType.GetProperties()); AssertEqual(expectedDependentProperties, dependentType.GetProperties()); - Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); - Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties).IsUnique); + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); + Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties)!.IsUnique); + } + else + { + Assert.Empty(dependentType.GetIndexes()); + } + Assert.Empty(principalType.GetIndexes()); } @@ -1144,8 +1377,16 @@ public virtual void Can_have_FK_by_convention_specified_with_explicit_principal_ AssertEqual(expectedPrincipalProperties, principalType.GetProperties()); AssertEqual(expectedDependentProperties, dependentType.GetProperties()); - Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); - Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties).IsUnique); + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); + Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties)!.IsUnique); + } + else + { + Assert.Empty(dependentType.GetIndexes()); + } + Assert.Empty(principalType.GetIndexes()); } @@ -1193,8 +1434,17 @@ public virtual void Can_have_FK_semi_specified_with_explicit_PK() Assert.False(fkProperty.IsNullable); expectedDependentProperties.Add(fkProperty); AssertEqual(expectedDependentProperties, dependentType.GetProperties()); - Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); - Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties).IsUnique); + + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); + Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties)!.IsUnique); + } + else + { + Assert.Empty(dependentType.GetIndexes()); + } + Assert.Empty(principalType.GetIndexes()); } @@ -1238,8 +1488,17 @@ public virtual void Can_specify_requiredness_after_OnDelete() Assert.False(fkProperty.IsNullable); expectedDependentProperties.Add(fkProperty); AssertEqual(expectedDependentProperties, dependentType.GetProperties()); - Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); - Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties).IsUnique); + + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); + Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties)!.IsUnique); + } + else + { + Assert.Empty(dependentType.GetIndexes()); + } + Assert.Empty(principalType.GetIndexes()); } @@ -1285,8 +1544,16 @@ public virtual void Can_have_principal_key_by_convention_specified_with_explicit Assert.Same(principalKey, principalType.FindPrimaryKey()); Assert.Same(dependentKey, dependentType.FindPrimaryKey()); - Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); - Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties).IsUnique); + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); + Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties)!.IsUnique); + } + else + { + Assert.Empty(dependentType.GetIndexes()); + } + Assert.Empty(principalType.GetIndexes()); } @@ -1332,8 +1599,16 @@ public virtual void Can_have_principal_key_by_convention_specified_with_explicit Assert.Same(principalKey, principalType.FindPrimaryKey()); Assert.Same(dependentKey, dependentType.FindPrimaryKey()); - Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); - Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties).IsUnique); + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); + Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties)!.IsUnique); + } + else + { + Assert.Empty(dependentType.GetIndexes()); + } + Assert.Empty(principalType.GetIndexes()); } @@ -1377,8 +1652,16 @@ public virtual void Can_have_principal_key_by_convention_replaced_with_primary_k Assert.Same(principalKey, principalType.FindPrimaryKey()); Assert.Same(dependentKey, dependentType.FindPrimaryKey()); - Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); - Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties).IsUnique); + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); + Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties)!.IsUnique); + } + else + { + Assert.Empty(dependentType.GetIndexes()); + } + Assert.Empty(principalType.GetIndexes()); } @@ -1423,8 +1706,16 @@ public virtual void Principal_key_by_convention_is_not_replaced_with_new_incompa Assert.Same(dependentKey, dependentType.FindPrimaryKey()); - Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); - Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties).IsUnique); + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); + Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties)!.IsUnique); + } + else + { + Assert.Empty(dependentType.GetIndexes()); + } + Assert.Empty(principalType.GetIndexes()); } @@ -1463,8 +1754,16 @@ public virtual void Explicit_principal_key_is_not_replaced_with_new_primary_key( var newKeyProperty = principalType.FindProperty(nameof(BigMak.AlternateKey)); Assert.Same(dependentKey, dependentType.FindPrimaryKey()); - Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); - Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties).IsUnique); + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); + Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties)!.IsUnique); + } + else + { + Assert.Empty(dependentType.GetIndexes()); + } + Assert.Empty(principalType.GetIndexes()); } @@ -1501,8 +1800,16 @@ public virtual void Creates_both_navigations_and_uses_existing_composite_FK() Assert.Same(principalKey, principalType.FindPrimaryKey()); Assert.Same(dependentKey, dependentType.FindPrimaryKey()); - Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); - Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties).IsUnique); + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); + Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties)!.IsUnique); + } + else + { + Assert.Empty(dependentType.GetIndexes()); + } + Assert.Empty(principalType.GetIndexes()); } @@ -1544,8 +1851,16 @@ public virtual void Creates_both_navigations_and_creates_composite_FK_specified( Assert.Same(principalKey, principalType.FindPrimaryKey()); Assert.Same(dependentKey, dependentType.FindPrimaryKey()); - Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); - Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties).IsUnique); + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); + Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties)!.IsUnique); + } + else + { + Assert.Empty(dependentType.GetIndexes()); + } + Assert.Empty(principalType.GetIndexes()); } @@ -1597,8 +1912,16 @@ public virtual void Can_use_alternate_composite_key() Assert.Same(principalKey, principalType.FindPrimaryKey()); Assert.Same(dependentKey, dependentType.FindPrimaryKey()); - Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); - Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties).IsUnique); + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); + Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties)!.IsUnique); + } + else + { + Assert.Empty(dependentType.GetIndexes()); + } + Assert.Empty(principalType.GetIndexes()); } @@ -1650,8 +1973,16 @@ public virtual void Can_use_alternate_composite_key_in_any_order() Assert.Same(principalKey, principalType.FindPrimaryKey()); Assert.Same(dependentKey, dependentType.FindPrimaryKey()); - Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); - Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties).IsUnique); + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); + Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties)!.IsUnique); + } + else + { + Assert.Empty(dependentType.GetIndexes()); + } + Assert.Empty(principalType.GetIndexes()); } @@ -1694,8 +2025,16 @@ public virtual void Creates_specified_composite_FK_with_navigation_to_dependent( Assert.Same(principalKey, principalType.FindPrimaryKey()); Assert.Same(dependentKey, dependentType.FindPrimaryKey()); - Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); - Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties).IsUnique); + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); + Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties)!.IsUnique); + } + else + { + Assert.Empty(dependentType.GetIndexes()); + } + Assert.Empty(principalType.GetIndexes()); } @@ -1731,8 +2070,16 @@ public virtual void Creates_specified_composite_FK_with_navigation_to_principal( Assert.Same(principalKey, principalType.FindPrimaryKey()); Assert.Same(dependentKey, dependentType.FindPrimaryKey()); - Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); - Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties).IsUnique); + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); + Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties)!.IsUnique); + } + else + { + Assert.Empty(dependentType.GetIndexes()); + } + Assert.Empty(principalType.GetIndexes()); } @@ -1773,8 +2120,16 @@ public virtual void Creates_relationship_with_no_navigations_and_specified_compo Assert.Same(principalKey, principalType.FindPrimaryKey()); Assert.Same(dependentKey, dependentType.FindPrimaryKey()); - Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); - Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties).IsUnique); + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); + Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties)!.IsUnique); + } + else + { + Assert.Empty(dependentType.GetIndexes()); + } + Assert.Empty(principalType.GetIndexes()); } @@ -1813,9 +2168,17 @@ public virtual void Creates_relationship_on_existing_FK_is_using_different_princ Assert.NotSame(principalKey, fk.PrincipalKey); Assert.NotEqual(existingFk.Properties, fk.Properties); Assert.Equal(principalType.GetForeignKeys().Count(), principalType.GetIndexes().Count()); - Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); - Assert.True(existingFk.DeclaringEntityType.FindIndex(existingFk.Properties).IsUnique); - Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties).IsUnique); + + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); + Assert.True(existingFk.DeclaringEntityType.FindIndex(existingFk.Properties)!.IsUnique); + Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties)!.IsUnique); + } + else + { + Assert.Empty(dependentType.GetIndexes()); + } Assert.Equal( CoreStrings.AmbiguousOneToOneRelationship( @@ -1858,8 +2221,16 @@ public virtual void Creates_relationship_on_existing_FK_is_using_different_princ Assert.NotSame(principalKey, fk.PrincipalKey); Assert.Equal(existingFk.Properties, fk.Properties); Assert.Empty(principalType.GetIndexes()); - Assert.Single(dependentType.GetIndexes()); - Assert.True(fk.DeclaringEntityType.FindIndex(fk.Properties).IsUnique); + + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Single(dependentType.GetIndexes()); + Assert.True(fk.DeclaringEntityType.FindIndex(fk.Properties)!.IsUnique); + } + else + { + Assert.Empty(dependentType.GetIndexes()); + } } [ConditionalFact] @@ -2004,8 +2375,16 @@ public virtual void Removes_existing_unidirectional_one_to_one_relationship() Assert.Equal(nameof(Nob.Hob), otherFk.DependentToPrincipal.Name); Assert.Same(principalKey, principalType.FindPrimaryKey()); Assert.Same(dependentKey, dependentType.FindPrimaryKey()); - Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); - Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties).IsUnique); + + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); + Assert.False(fk.DeclaringEntityType.FindIndex(fk.Properties)!.IsUnique); + } + else + { + Assert.Empty(dependentType.GetIndexes()); + } } [ConditionalFact] diff --git a/test/EFCore.Specification.Tests/ModelBuilding/ModelBuilderTest.OneToOne.cs b/test/EFCore.Specification.Tests/ModelBuilding/ModelBuilderTest.OneToOne.cs index f0076f63460..387163f1930 100644 --- a/test/EFCore.Specification.Tests/ModelBuilding/ModelBuilderTest.OneToOne.cs +++ b/test/EFCore.Specification.Tests/ModelBuilding/ModelBuilderTest.OneToOne.cs @@ -149,8 +149,17 @@ public virtual void Replaces_existing_navigation_to_principal() Assert.Same(fk, principalType.GetNavigations().Single().ForeignKey); Assert.Same(principalKey, principalType.FindPrimaryKey()); Assert.Same(dependentKey, dependentType.FindPrimaryKey()); - Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); - Assert.True(fk.DeclaringEntityType.FindIndex(fk.Properties).IsUnique); + + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); + Assert.True(fk.DeclaringEntityType.FindIndex(fk.Properties)!.IsUnique); + } + else + { + Assert.Empty(dependentType.GetIndexes()); + } + Assert.Empty(principalType.GetIndexes()); } @@ -212,8 +221,17 @@ public virtual void Creates_both_navigations_and_shadow_FK_if_existing_FK() Assert.Empty(principalType.GetForeignKeys()); Assert.Same(principalKey, principalType.FindPrimaryKey()); Assert.Same(dependentKey, dependentType.FindPrimaryKey()); - Assert.Single(dependentType.GetIndexes()); - Assert.True(fk.DeclaringEntityType.FindIndex(fk.Properties).IsUnique); + + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Single(dependentType.GetIndexes()); + Assert.True(fk.DeclaringEntityType.FindIndex(fk.Properties).IsUnique); + } + else + { + Assert.Empty(dependentType.GetIndexes()); + } + Assert.Empty(principalType.GetIndexes()); } @@ -240,8 +258,17 @@ public virtual void Creates_both_navigations_and_new_FK() Assert.Equal(nameof(Customer.Details), principalType.GetNavigations().Single().Name); Assert.Same(principalKey, principalType.FindPrimaryKey()); Assert.Same(dependentKey, dependentType.FindPrimaryKey()); - Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); - Assert.True(fk.DeclaringEntityType.FindIndex(fk.Properties).IsUnique); + + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); + Assert.True(fk.DeclaringEntityType.FindIndex(fk.Properties)!.IsUnique); + } + else + { + Assert.Empty(dependentType.GetIndexes()); + } + Assert.Empty(principalType.GetIndexes()); } @@ -302,8 +329,17 @@ public virtual void Creates_both_navigations_and_creates_new_FK_when_not_specifi Assert.Empty(principalType.GetForeignKeys()); Assert.Same(principalKey, principalType.FindPrimaryKey()); Assert.Same(dependentKey, dependentType.FindPrimaryKey()); - Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); - Assert.True(fk.DeclaringEntityType.FindIndex(fk.Properties).IsUnique); + + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); + Assert.True(fk.DeclaringEntityType.FindIndex(fk.Properties)!.IsUnique); + } + else + { + Assert.Empty(dependentType.GetIndexes()); + } + Assert.Empty(principalType.GetIndexes()); } @@ -365,11 +401,19 @@ public virtual void Creates_relationship_with_navigation_to_dependent_and_new_FK var fk = dependentType.GetNavigations().Single().ForeignKey; Assert.True(fk.IsUnique); Assert.NotSame(fk, principalType.GetNavigations().Single().ForeignKey); - Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); - Assert.True(fk.DeclaringEntityType.FindIndex(fk.Properties).IsUnique); - Assert.True( - principalType.GetForeignKeys() - .All(foreignKey => principalType.FindIndex(foreignKey.Properties).IsUnique == foreignKey.IsUnique)); + + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); + Assert.True(fk.DeclaringEntityType.FindIndex(fk.Properties)!.IsUnique); + Assert.True( + principalType.GetForeignKeys() + .All(foreignKey => principalType.FindIndex(foreignKey.Properties).IsUnique == foreignKey.IsUnique)); + } + else + { + Assert.Empty(dependentType.GetIndexes()); + } } [ConditionalFact] @@ -393,8 +437,17 @@ public virtual void Creates_relationship_with_navigation_to_dependent_and_new_FK Assert.True(fk.IsUnique); Assert.NotSame(fk, dependentType.GetNavigations().Single().ForeignKey); Assert.Empty(principalType.GetForeignKeys()); - Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); - Assert.True(fk.DeclaringEntityType.FindIndex(fk.Properties).IsUnique); + + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); + Assert.True(fk.DeclaringEntityType.FindIndex(fk.Properties)!.IsUnique); + } + else + { + Assert.Empty(dependentType.GetIndexes()); + } + Assert.Empty(principalType.GetIndexes()); } @@ -425,8 +478,17 @@ public virtual void Creates_relationship_with_no_navigations() AssertEqual(expectedDependentProperties, dependentType.GetProperties()); Assert.Same(principalKey, principalType.FindPrimaryKey()); Assert.Same(dependentKey, dependentType.FindPrimaryKey()); - Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); - Assert.True(fk.DeclaringEntityType.FindIndex(fk.Properties).IsUnique); + + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); + Assert.True(fk.DeclaringEntityType.FindIndex(fk.Properties)!.IsUnique); + } + else + { + Assert.Empty(dependentType.GetIndexes()); + } + Assert.Equal(principalType.GetForeignKeys().Count(), principalType.GetIndexes().Count()); } @@ -462,8 +524,17 @@ public virtual void Creates_both_navigations_and_uses_specified_FK_even_if_found Assert.Empty(principalType.GetForeignKeys()); Assert.Same(principalKey, principalType.FindPrimaryKey()); Assert.Same(dependentKey, dependentType.FindPrimaryKey()); - Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); - Assert.True(fk.DeclaringEntityType.FindIndex(fk.Properties).IsUnique); + + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); + Assert.True(fk.DeclaringEntityType.FindIndex(fk.Properties)!.IsUnique); + } + else + { + Assert.Empty(dependentType.GetIndexes()); + } + Assert.Empty(principalType.GetIndexes()); } @@ -533,8 +604,17 @@ public virtual void Creates_both_navigations_and_uses_existing_FK_not_found_by_c Assert.Empty(principalType.GetForeignKeys()); Assert.Same(principalKey, principalType.FindPrimaryKey()); Assert.Same(dependentKey, dependentType.FindPrimaryKey()); - Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); - Assert.True(fk.DeclaringEntityType.FindIndex(fk.Properties).IsUnique); + + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); + Assert.True(fk.DeclaringEntityType.FindIndex(fk.Properties)!.IsUnique); + } + else + { + Assert.Empty(dependentType.GetIndexes()); + } + Assert.Empty(principalType.GetIndexes()); } @@ -569,8 +649,17 @@ public virtual void Creates_both_navigations_and_specified_FK() Assert.Empty(principalType.GetForeignKeys()); Assert.Same(principalKey, principalType.FindPrimaryKey()); Assert.Same(dependentKey, dependentType.FindPrimaryKey()); - Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); - Assert.True(fk.DeclaringEntityType.FindIndex(fk.Properties).IsUnique); + + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); + Assert.True(fk.DeclaringEntityType.FindIndex(fk.Properties)!.IsUnique); + } + else + { + Assert.Empty(dependentType.GetIndexes()); + } + Assert.Empty(principalType.GetIndexes()); } @@ -602,8 +691,17 @@ public virtual void Creates_relationship_with_specified_FK_with_navigation_to_de Assert.Equal(nameof(BigMak.Bun), principalType.GetNavigations().Single().Name); Assert.Same(principalKey, principalType.FindPrimaryKey()); Assert.Same(dependentKey, dependentType.FindPrimaryKey()); - Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); - Assert.True(fk.DeclaringEntityType.FindIndex(fk.Properties).IsUnique); + + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); + Assert.True(fk.DeclaringEntityType.FindIndex(fk.Properties)!.IsUnique); + } + else + { + Assert.Empty(dependentType.GetIndexes()); + } + Assert.Empty(principalType.GetIndexes()); } @@ -637,11 +735,19 @@ public virtual void Creates_relationship_with_specified_FK_with_navigation_to_pr Assert.Same(principalKey, principalType.FindPrimaryKey()); Assert.Same(dependentKey, dependentType.FindPrimaryKey()); Assert.True(fk.IsUnique); - Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); - Assert.True(fk.DeclaringEntityType.FindIndex(fk.Properties).IsUnique); - Assert.True( - principalType.GetForeignKeys() - .All(foreignKey => principalType.FindIndex(foreignKey.Properties).IsUnique == foreignKey.IsUnique)); + + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); + Assert.True(fk.DeclaringEntityType.FindIndex(fk.Properties)!.IsUnique); + Assert.True( + principalType.GetForeignKeys() + .All(foreignKey => principalType.FindIndex(foreignKey.Properties).IsUnique == foreignKey.IsUnique)); + } + else + { + Assert.Empty(dependentType.GetIndexes()); + } } [ConditionalFact] @@ -675,8 +781,17 @@ public virtual void Creates_relationship_with_specified_FK_with_no_navigations() Assert.Equal(expectedDependentProperties, dependentType.GetProperties()); Assert.Same(principalKey, principalType.FindPrimaryKey()); Assert.Same(dependentKey, dependentType.FindPrimaryKey()); - Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); - Assert.True(fk.DeclaringEntityType.FindIndex(fk.Properties).IsUnique); + + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); + Assert.True(fk.DeclaringEntityType.FindIndex(fk.Properties)!.IsUnique); + } + else + { + Assert.Empty(dependentType.GetIndexes()); + } + Assert.Empty(principalType.GetIndexes()); } @@ -711,8 +826,17 @@ public virtual void Creates_both_navigations_and_overrides_existing_FK_when_uniq Assert.Empty(principalType.GetForeignKeys()); Assert.Same(principalKey, principalType.FindPrimaryKey()); Assert.Same(dependentKey, dependentType.FindPrimaryKey()); - Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); - Assert.True(fk.DeclaringEntityType.FindIndex(fk.Properties).IsUnique); + + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); + Assert.True(fk.DeclaringEntityType.FindIndex(fk.Properties)!.IsUnique); + } + else + { + Assert.Empty(dependentType.GetIndexes()); + } + Assert.Empty(principalType.GetIndexes()); } @@ -789,8 +913,17 @@ public virtual void Creates_FK_when_specified_on_dependent() Assert.Empty(principalType.GetForeignKeys()); Assert.Same(principalKey, principalType.FindPrimaryKey()); Assert.Same(dependentKey, dependentType.FindPrimaryKey()); - Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); - Assert.True(fk.DeclaringEntityType.FindIndex(fk.Properties).IsUnique); + + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); + Assert.True(fk.DeclaringEntityType.FindIndex(fk.Properties)!.IsUnique); + } + else + { + Assert.Empty(dependentType.GetIndexes()); + } + Assert.Empty(principalType.GetIndexes()); } @@ -891,10 +1024,18 @@ public virtual void Creates_FK_when_specified_on_dependent_with_navigation_to_pr Assert.NotSame(fk, principalType.GetNavigations().Single().ForeignKey); Assert.Same(principalKey, principalType.FindPrimaryKey()); Assert.Same(dependentKey, dependentType.FindPrimaryKey()); - Assert.Equal(dependentType.GetForeignKeys().Count() - 1, dependentType.GetIndexes().Count()); - Assert.True( - principalType.GetForeignKeys() - .All(foreignKey => principalType.FindIndex(foreignKey.Properties).IsUnique == foreignKey.IsUnique)); + + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Equal(dependentType.GetForeignKeys().Count() - 1, dependentType.GetIndexes().Count()); + Assert.True( + principalType.GetForeignKeys() + .All(foreignKey => principalType.FindIndex(foreignKey.Properties)!.IsUnique == foreignKey.IsUnique)); + } + else + { + Assert.Empty(dependentType.GetIndexes()); + } } [ConditionalFact] @@ -926,10 +1067,18 @@ public virtual void Creates_FK_when_specified_on_principal_with_navigation_to_pr Assert.Same(principalKey, principalType.FindPrimaryKey()); Assert.Same(dependentKey, dependentType.FindPrimaryKey()); Assert.Empty(dependentType.GetIndexes()); - Assert.Equal(principalType.GetForeignKeys().Count(), principalType.GetIndexes().Count()); - Assert.True( - principalType.GetForeignKeys() - .All(foreignKey => principalType.FindIndex(foreignKey.Properties).IsUnique == foreignKey.IsUnique)); + + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Equal(principalType.GetForeignKeys().Count(), principalType.GetIndexes().Count()); + Assert.True( + principalType.GetForeignKeys() + .All(foreignKey => principalType.FindIndex(foreignKey.Properties)!.IsUnique == foreignKey.IsUnique)); + } + else + { + Assert.Empty(principalType.GetIndexes()); + } } [ConditionalFact] @@ -960,7 +1109,16 @@ public virtual void Creates_FK_when_specified_on_dependent_with_navigation_to_de Assert.NotSame(fk, dependentType.GetNavigations().Single().ForeignKey); Assert.Same(principalKey, principalType.FindPrimaryKey()); Assert.Same(dependentKey, dependentType.FindPrimaryKey()); - Assert.Equal(dependentType.GetForeignKeys().Count() - 1, dependentType.GetIndexes().Count()); + + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Equal(dependentType.GetForeignKeys().Count() - 1, dependentType.GetIndexes().Count()); + } + else + { + Assert.Empty(dependentType.GetIndexes()); + } + Assert.Empty(principalType.GetIndexes()); } @@ -992,10 +1150,18 @@ public virtual void Creates_FK_when_specified_on_dependent_with_no_navigations() Assert.Same(existingFk, principalType.GetNavigations().Single().ForeignKey); Assert.Same(principalKey, principalType.FindPrimaryKey()); Assert.Same(dependentKey, dependentType.FindPrimaryKey()); - Assert.Equal(dependentType.GetForeignKeys().Count() - 1, dependentType.GetIndexes().Count()); - Assert.True( - principalType.GetForeignKeys() - .All(foreignKey => principalType.FindIndex(foreignKey.Properties).IsUnique == foreignKey.IsUnique)); + + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Equal(dependentType.GetForeignKeys().Count() - 1, dependentType.GetIndexes().Count()); + Assert.True( + principalType.GetForeignKeys() + .All(foreignKey => principalType.FindIndex(foreignKey.Properties)!.IsUnique == foreignKey.IsUnique)); + } + else + { + Assert.Empty(dependentType.GetIndexes()); + } } [ConditionalFact] @@ -1034,9 +1200,17 @@ public virtual void Creates_FK_when_specified_on_principal_with_no_navigations() Assert.Same(principalKey, principalType.FindPrimaryKey()); Assert.Same(dependentKey, dependentType.FindPrimaryKey()); Assert.Empty(dependentType.GetIndexes()); - Assert.True( - principalType.GetForeignKeys() - .All(foreignKey => principalType.FindIndex(foreignKey.Properties).IsUnique == foreignKey.IsUnique)); + + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.True( + principalType.GetForeignKeys() + .All(foreignKey => principalType.FindIndex(foreignKey.Properties)!.IsUnique == foreignKey.IsUnique)); + } + else + { + Assert.Empty(principalType.GetIndexes()); + } } [ConditionalFact] @@ -1107,8 +1281,17 @@ public virtual void OneToOne_can_have_PK_explicitly_specified() Assert.Empty(principalType.GetForeignKeys()); Assert.Same(principalKey, principalType.FindPrimaryKey()); Assert.Same(dependentKey, dependentType.FindPrimaryKey()); - Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); - Assert.True(fk.DeclaringEntityType.FindIndex(fk.Properties).IsUnique); + + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); + Assert.True(fk.DeclaringEntityType.FindIndex(fk.Properties)!.IsUnique); + } + else + { + Assert.Empty(dependentType.GetIndexes()); + } + Assert.Empty(principalType.GetIndexes()); } @@ -1147,8 +1330,16 @@ public virtual void Can_use_alternate_principal_key() Assert.Same(principalKey, principalType.FindPrimaryKey()); Assert.Same(dependentKey, dependentType.FindPrimaryKey()); - Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); - Assert.True(fk.DeclaringEntityType.FindIndex(fk.Properties).IsUnique); + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); + Assert.True(fk.DeclaringEntityType.FindIndex(fk.Properties)!.IsUnique); + } + else + { + Assert.Empty(dependentType.GetIndexes()); + } + Assert.Empty(principalType.GetIndexes()); } @@ -1193,8 +1384,17 @@ public virtual void Can_have_both_keys_specified_explicitly() Assert.Empty(principalType.GetForeignKeys()); Assert.Same(principalKey, principalType.FindPrimaryKey()); Assert.Same(dependentKey, dependentType.FindPrimaryKey()); - Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); - Assert.True(fk.DeclaringEntityType.FindIndex(fk.Properties).IsUnique); + + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); + Assert.True(fk.DeclaringEntityType.FindIndex(fk.Properties)!.IsUnique); + } + else + { + Assert.Empty(dependentType.GetIndexes()); + } + Assert.Empty(principalType.GetIndexes()); } @@ -1239,8 +1439,17 @@ public virtual void Can_have_both_keys_specified_explicitly_in_any_order() Assert.Empty(principalType.GetForeignKeys()); Assert.Same(principalKey, principalType.FindPrimaryKey()); Assert.Same(dependentKey, dependentType.FindPrimaryKey()); - Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); - Assert.True(fk.DeclaringEntityType.FindIndex(fk.Properties).IsUnique); + + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); + Assert.True(fk.DeclaringEntityType.FindIndex(fk.Properties)!.IsUnique); + } + else + { + Assert.Empty(dependentType.GetIndexes()); + } + Assert.Empty(principalType.GetIndexes()); } @@ -1284,8 +1493,16 @@ public virtual void Can_have_both_alternate_keys_specified_explicitly() Assert.Same(principalKey, principalType.FindPrimaryKey()); Assert.Same(dependentKey, dependentType.FindPrimaryKey()); - Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); - Assert.True(fk.DeclaringEntityType.FindIndex(fk.Properties).IsUnique); + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); + Assert.True(fk.DeclaringEntityType.FindIndex(fk.Properties)!.IsUnique); + } + else + { + Assert.Empty(dependentType.GetIndexes()); + } + Assert.Empty(principalType.GetIndexes()); } @@ -1329,8 +1546,16 @@ public virtual void Can_have_both_alternate_keys_specified_explicitly_in_any_ord Assert.Same(principalKey, principalType.FindPrimaryKey()); Assert.Same(dependentKey, dependentType.FindPrimaryKey()); - Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); - Assert.True(fk.DeclaringEntityType.FindIndex(fk.Properties).IsUnique); + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); + Assert.True(fk.DeclaringEntityType.FindIndex(fk.Properties)!.IsUnique); + } + else + { + Assert.Empty(dependentType.GetIndexes()); + } + Assert.Empty(principalType.GetIndexes()); } @@ -1401,8 +1626,17 @@ public virtual void Does_not_use_existing_FK_when_principal_key_specified() Assert.Empty(principalType.GetForeignKeys()); Assert.Same(principalKey, principalType.FindPrimaryKey()); Assert.Same(dependentKey, dependentType.FindPrimaryKey()); - Assert.Single(dependentType.GetIndexes()); - Assert.True(fk.DeclaringEntityType.FindIndex(fk.Properties).IsUnique); + + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Single(dependentType.GetIndexes()); + Assert.True(fk.DeclaringEntityType.FindIndex(fk.Properties)!.IsUnique); + } + else + { + Assert.Empty(dependentType.GetIndexes()); + } + Assert.Empty(principalType.GetIndexes()); } @@ -1442,8 +1676,17 @@ public virtual void Creates_principal_key_when_specified_on_dependent() Assert.Empty(principalType.GetForeignKeys()); Assert.Same(principalKey, principalType.FindPrimaryKey()); Assert.Same(dependentKey, dependentType.FindPrimaryKey()); - Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); - Assert.True(fk.DeclaringEntityType.FindIndex(fk.Properties).IsUnique); + + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); + Assert.True(fk.DeclaringEntityType.FindIndex(fk.Properties)!.IsUnique); + } + else + { + Assert.Empty(dependentType.GetIndexes()); + } + Assert.Empty(principalType.GetIndexes()); } @@ -1524,8 +1767,17 @@ public virtual void Creates_FK_when_principal_and_foreign_key_specified_on_depen Assert.Empty(principalType.GetForeignKeys()); Assert.Same(principalKey, principalType.FindPrimaryKey()); Assert.Same(dependentKey, dependentType.FindPrimaryKey()); - Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); - Assert.True(fk.DeclaringEntityType.FindIndex(fk.Properties).IsUnique); + + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); + Assert.True(fk.DeclaringEntityType.FindIndex(fk.Properties)!.IsUnique); + } + else + { + Assert.Empty(dependentType.GetIndexes()); + } + Assert.Empty(principalType.GetIndexes()); } @@ -1565,8 +1817,17 @@ public virtual void Creates_FK_when_principal_and_foreign_key_specified_on_depen Assert.Empty(principalType.GetForeignKeys()); Assert.Same(principalKey, principalType.FindPrimaryKey()); Assert.Same(dependentKey, dependentType.FindPrimaryKey()); - Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); - Assert.True(fk.DeclaringEntityType.FindIndex(fk.Properties).IsUnique); + + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); + Assert.True(fk.DeclaringEntityType.FindIndex(fk.Properties)!.IsUnique); + } + else + { + Assert.Empty(dependentType.GetIndexes()); + } + Assert.Empty(principalType.GetIndexes()); } @@ -1879,8 +2140,17 @@ public virtual void Creates_principal_key_when_specified_on_principal_with_navig Assert.Equal(nameof(Customer.Details), fk.PrincipalToDependent.Name); Assert.Same(principalKey, principalType.FindPrimaryKey()); Assert.Same(dependentKey, dependentType.FindPrimaryKey()); - Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); - Assert.True(fk.DeclaringEntityType.FindIndex(fk.Properties).IsUnique); + + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); + Assert.True(fk.DeclaringEntityType.FindIndex(fk.Properties)!.IsUnique); + } + else + { + Assert.Empty(dependentType.GetIndexes()); + } + Assert.Empty(principalType.GetIndexes()); } @@ -1910,8 +2180,16 @@ public virtual void Creates_principal_key_when_specified_on_dependent_with_navig Assert.Same(principalKey, principalType.FindPrimaryKey()); Assert.Same(dependentKey, dependentType.FindPrimaryKey()); Assert.True(fk.IsUnique); - Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); - Assert.True(fk.DeclaringEntityType.FindIndex(fk.Properties).IsUnique); + + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); + Assert.True(fk.DeclaringEntityType.FindIndex(fk.Properties)!.IsUnique); + } + else + { + Assert.Empty(dependentType.GetIndexes()); + } } [ConditionalFact] @@ -1939,9 +2217,16 @@ public virtual void Creates_principal_key_when_specified_on_principal_with_navig Assert.NotSame(fk, principalType.GetNavigations().Single().ForeignKey); Assert.Same(principalKey, principalType.FindPrimaryKey()); Assert.Same(dependentKey, dependentType.FindPrimaryKey()); - Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); - Assert.True(fk.DeclaringEntityType.FindIndex(fk.Properties).IsUnique); - Assert.Equal(principalType.GetForeignKeys().Count(), principalType.GetIndexes().Count()); + + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); + Assert.True(fk.DeclaringEntityType.FindIndex(fk.Properties)!.IsUnique); + } + else + { + Assert.Empty(dependentType.GetIndexes()); + } } [ConditionalFact] @@ -1970,8 +2255,17 @@ public virtual void Creates_principal_key_when_specified_on_dependent_with_navig Assert.Empty(principalType.GetForeignKeys()); Assert.Same(principalKey, principalType.FindPrimaryKey()); Assert.Same(dependentKey, dependentType.FindPrimaryKey()); - Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); - Assert.True(fk.DeclaringEntityType.FindIndex(fk.Properties).IsUnique); + + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); + Assert.True(fk.DeclaringEntityType.FindIndex(fk.Properties)!.IsUnique); + } + else + { + Assert.Empty(dependentType.GetIndexes()); + } + Assert.Empty(principalType.GetIndexes()); } @@ -2012,8 +2306,17 @@ public virtual void Creates_principal_key_when_specified_on_principal_with_no_na Assert.Empty(principalType.GetForeignKeys()); Assert.Same(principalKey, principalType.FindPrimaryKey()); Assert.Same(dependentKey, dependentType.FindPrimaryKey()); - Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); - Assert.True(fk.DeclaringEntityType.FindIndex(fk.Properties).IsUnique); + + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); + Assert.True(fk.DeclaringEntityType.FindIndex(fk.Properties)!.IsUnique); + } + else + { + Assert.Empty(dependentType.GetIndexes()); + } + Assert.Empty(principalType.GetIndexes()); } @@ -2049,8 +2352,17 @@ public virtual void Creates_principal_key_when_specified_on_dependent_with_no_na Assert.Empty(principalType.GetForeignKeys()); Assert.Same(principalKey, principalType.FindPrimaryKey()); Assert.Same(dependentKey, dependentType.FindPrimaryKey()); - Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); - Assert.True(fk.DeclaringEntityType.FindIndex(fk.Properties).IsUnique); + + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); + Assert.True(fk.DeclaringEntityType.FindIndex(fk.Properties)!.IsUnique); + } + else + { + Assert.Empty(dependentType.GetIndexes()); + } + Assert.Empty(principalType.GetIndexes()); } @@ -2088,8 +2400,17 @@ public virtual void Creates_both_navigations_and_uses_existing_composite_FK() Assert.Empty(principalType.GetForeignKeys()); Assert.Same(principalKey, principalType.FindPrimaryKey()); Assert.Same(dependentKey, dependentType.FindPrimaryKey()); - Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); - Assert.True(fk.DeclaringEntityType.FindIndex(fk.Properties).IsUnique); + + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); + Assert.True(fk.DeclaringEntityType.FindIndex(fk.Properties)!.IsUnique); + } + else + { + Assert.Empty(dependentType.GetIndexes()); + } + Assert.Empty(principalType.GetIndexes()); } @@ -2128,8 +2449,17 @@ public virtual void Creates_both_navigations_and_creates_composite_FK_specified( Assert.Empty(principalType.GetForeignKeys()); Assert.Same(principalKey, principalType.FindPrimaryKey()); Assert.Same(dependentKey, dependentType.FindPrimaryKey()); - Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); - Assert.True(fk.DeclaringEntityType.FindIndex(fk.Properties).IsUnique); + + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); + Assert.True(fk.DeclaringEntityType.FindIndex(fk.Properties)!.IsUnique); + } + else + { + Assert.Empty(dependentType.GetIndexes()); + } + Assert.Empty(principalType.GetIndexes()); } @@ -2182,8 +2512,16 @@ public virtual void Can_use_alternate_composite_key() Assert.Same(principalKey, principalType.FindPrimaryKey()); Assert.Same(dependentKey, dependentType.FindPrimaryKey()); - Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); - Assert.True(fk.DeclaringEntityType.FindIndex(fk.Properties).IsUnique); + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); + Assert.True(fk.DeclaringEntityType.FindIndex(fk.Properties)!.IsUnique); + } + else + { + Assert.Empty(dependentType.GetIndexes()); + } + Assert.Empty(principalType.GetIndexes()); } @@ -2236,8 +2574,16 @@ public virtual void Can_use_alternate_composite_key_in_any_order() Assert.Same(principalKey, principalType.FindPrimaryKey()); Assert.Same(dependentKey, dependentType.FindPrimaryKey()); - Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); - Assert.True(fk.DeclaringEntityType.FindIndex(fk.Properties).IsUnique); + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); + Assert.True(fk.DeclaringEntityType.FindIndex(fk.Properties)!.IsUnique); + } + else + { + Assert.Empty(dependentType.GetIndexes()); + } + Assert.Empty(principalType.GetIndexes()); } @@ -2403,8 +2749,17 @@ public virtual void Creates_composite_FK_when_specified_on_principal_with_naviga Assert.Null(fk.DependentToPrincipal); Assert.Same(principalKey, principalType.FindPrimaryKey()); Assert.Same(dependentKey, dependentType.FindPrimaryKey()); - Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); - Assert.True(fk.DeclaringEntityType.FindIndex(fk.Properties).IsUnique); + + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); + Assert.True(fk.DeclaringEntityType.FindIndex(fk.Properties)!.IsUnique); + } + else + { + Assert.Empty(dependentType.GetIndexes()); + } + Assert.Empty(principalType.GetIndexes()); } @@ -2443,11 +2798,19 @@ public virtual void Creates_composite_FK_when_specified_on_principal_with_naviga Assert.Same(principalKey, principalType.FindPrimaryKey()); Assert.Same(dependentKey, dependentType.FindPrimaryKey()); Assert.True(fk.IsUnique); - Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); - Assert.True(fk.DeclaringEntityType.FindIndex(fk.Properties).IsUnique); - Assert.True( - principalType.GetForeignKeys() - .All(foreignKey => principalType.FindIndex(foreignKey.Properties).IsUnique == foreignKey.IsUnique)); + + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); + Assert.True(fk.DeclaringEntityType.FindIndex(fk.Properties)!.IsUnique); + Assert.True( + principalType.GetForeignKeys() + .All(foreignKey => principalType.FindIndex(foreignKey.Properties)!.IsUnique == foreignKey.IsUnique)); + } + else + { + Assert.Empty(dependentType.GetIndexes()); + } } [ConditionalFact] @@ -2485,11 +2848,19 @@ public virtual void Creates_composite_FK_when_specified_on_principal_with_no_nav Assert.Empty(principalType.GetNavigations().Where(nav => nav.ForeignKey == fk)); Assert.Same(principalKey, principalType.FindPrimaryKey()); Assert.Same(dependentKey, dependentType.FindPrimaryKey()); - Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); - Assert.True(fk.DeclaringEntityType.FindIndex(fk.Properties).IsUnique); - Assert.True( - principalType.GetForeignKeys() - .All(foreignKey => principalType.FindIndex(foreignKey.Properties).IsUnique == foreignKey.IsUnique)); + + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); + Assert.True(fk.DeclaringEntityType.FindIndex(fk.Properties)!.IsUnique); + Assert.True( + principalType.GetForeignKeys() + .All(foreignKey => principalType.FindIndex(foreignKey.Properties).IsUnique == foreignKey.IsUnique)); + } + else + { + Assert.Empty(dependentType.GetIndexes()); + } } [ConditionalFact] @@ -2518,8 +2889,15 @@ public virtual void Principal_and_dependent_can_be_flipped_when_self_referencing Assert.Equal(navigationToDependent.Name, fk.DependentToPrincipal.Name); Assert.True(fk.IsRequired); - Assert.Equal(fk.DeclaringEntityType.GetForeignKeys().Count(), fk.DeclaringEntityType.GetIndexes().Count()); - Assert.True(fk.DeclaringEntityType.FindIndex(fk.Properties).IsUnique); + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Equal(fk.DeclaringEntityType.GetForeignKeys().Count(), fk.DeclaringEntityType.GetIndexes().Count()); + Assert.True(fk.DeclaringEntityType.FindIndex(fk.Properties)!.IsUnique); + } + else + { + Assert.Empty(fk.DeclaringEntityType.GetIndexes()); + } modelBuilder.FinalizeModel(); } @@ -2548,8 +2926,16 @@ public virtual void Creates_self_referencing_FK_with_navigation_to_principal() Assert.Null(fk.PrincipalToDependent); Assert.Equal(nameof(SelfRef.SelfRef1), fk.DependentToPrincipal?.Name); Assert.Equal(2, entityType.GetNavigations().Count()); - Assert.Equal(fk.DeclaringEntityType.GetForeignKeys().Count(), fk.DeclaringEntityType.GetIndexes().Count()); - Assert.True(fk.DeclaringEntityType.FindIndex(fk.Properties).IsUnique); + + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Equal(fk.DeclaringEntityType.GetForeignKeys().Count(), fk.DeclaringEntityType.GetIndexes().Count()); + Assert.True(fk.DeclaringEntityType.FindIndex(fk.Properties)!.IsUnique); + } + else + { + Assert.Empty(fk.DeclaringEntityType.GetIndexes()); + } } [ConditionalFact] @@ -2576,8 +2962,16 @@ public virtual void Creates_self_referencing_FK_with_navigation_to_dependent() Assert.Equal(nameof(SelfRef.SelfRef1), fk.PrincipalToDependent?.Name); Assert.Null(fk.DependentToPrincipal); Assert.Equal(2, entityType.GetNavigations().Count()); - Assert.Equal(fk.DeclaringEntityType.GetForeignKeys().Count(), fk.DeclaringEntityType.GetIndexes().Count()); - Assert.True(fk.DeclaringEntityType.FindIndex(fk.Properties).IsUnique); + + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Equal(fk.DeclaringEntityType.GetForeignKeys().Count(), fk.DeclaringEntityType.GetIndexes().Count()); + Assert.True(fk.DeclaringEntityType.FindIndex(fk.Properties)!.IsUnique); + } + else + { + Assert.Empty(fk.DeclaringEntityType.GetIndexes()); + } } [ConditionalFact] @@ -2636,8 +3030,15 @@ public virtual void Principal_and_dependent_can_be_flipped_when_self_referencing Assert.True(fk.IsRequired); Assert.False(fk.IsRequiredDependent); - Assert.Equal(fk.DeclaringEntityType.GetForeignKeys().Count(), fk.DeclaringEntityType.GetIndexes().Count()); - Assert.True(fk.DeclaringEntityType.FindIndex(fk.Properties).IsUnique); + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Equal(fk.DeclaringEntityType.GetForeignKeys().Count(), fk.DeclaringEntityType.GetIndexes().Count()); + Assert.True(fk.DeclaringEntityType.FindIndex(fk.Properties)!.IsUnique); + } + else + { + Assert.Empty(fk.DeclaringEntityType.GetIndexes()); + } } [ConditionalFact] @@ -2669,8 +3070,15 @@ public virtual void Principal_and_dependent_can_be_flipped_when_self_referencing Assert.Equal(navigationToDependent.Name, newFk.DependentToPrincipal.Name); Assert.True(newFk.IsUnique); - Assert.Equal(fk.DeclaringEntityType.GetForeignKeys().Count(), fk.DeclaringEntityType.GetIndexes().Count()); - Assert.True(fk.DeclaringEntityType.FindIndex(fk.Properties).IsUnique); + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Equal(fk.DeclaringEntityType.GetForeignKeys().Count(), fk.DeclaringEntityType.GetIndexes().Count()); + Assert.True(fk.DeclaringEntityType.FindIndex(fk.Properties)!.IsUnique); + } + else + { + Assert.Empty(fk.DeclaringEntityType.GetIndexes()); + } } [ConditionalFact] @@ -2703,8 +3111,16 @@ public virtual void Creates_self_referencing_FK_by_convention() Assert.Equal(nameof(SelfRef.SelfRef2), fk.PrincipalToDependent?.Name); Assert.Equal(nameof(SelfRef.SelfRef1), fk.DependentToPrincipal?.Name); Assert.Equal(2, entityType.GetNavigations().Count()); - Assert.Single(fk.DeclaringEntityType.GetIndexes()); - Assert.True(fk.DeclaringEntityType.FindIndex(fk.Properties).IsUnique); + + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Single(fk.DeclaringEntityType.GetIndexes()); + Assert.True(fk.DeclaringEntityType.FindIndex(fk.Properties)!.IsUnique); + } + else + { + Assert.Empty(fk.DeclaringEntityType.GetIndexes()); + } } [ConditionalFact] @@ -2724,8 +3140,16 @@ public virtual void Creates_self_referencing_FK_by_convention_inverted() Assert.Equal(nameof(SelfRef.SelfRef1), fk.PrincipalToDependent?.Name); Assert.Equal(nameof(SelfRef.SelfRef2), fk.DependentToPrincipal?.Name); Assert.Equal(2, entityType.GetNavigations().Count()); - Assert.Single(fk.DeclaringEntityType.GetIndexes()); - Assert.True(fk.DeclaringEntityType.FindIndex(fk.Properties).IsUnique); + + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Single(fk.DeclaringEntityType.GetIndexes()); + Assert.True(fk.DeclaringEntityType.FindIndex(fk.Properties)!.IsUnique); + } + else + { + Assert.Empty(fk.DeclaringEntityType.GetIndexes()); + } } [ConditionalFact] @@ -3096,9 +3520,18 @@ public virtual void Creates_relationship_on_existing_FK_if_using_different_princ var fk = dependentType.GetForeignKeys().Single(foreignKey => foreignKey != existingFk); Assert.NotSame(principalKey, fk.PrincipalKey); Assert.Empty(principalType.GetIndexes()); - Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); - Assert.False(existingFk.DeclaringEntityType.FindIndex(existingFk.Properties).IsUnique); - Assert.True(fk.DeclaringEntityType.FindIndex(fk.Properties).IsUnique); + + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); + Assert.False(existingFk.DeclaringEntityType.FindIndex(existingFk.Properties)!.IsUnique); + Assert.True(fk.DeclaringEntityType.FindIndex(fk.Properties)!.IsUnique); + } + else + { + Assert.Empty(fk.DeclaringEntityType.GetIndexes()); + } + Assert.Empty(principalType.GetIndexes()); } @@ -3140,8 +3573,17 @@ public virtual void Creates_relationship_on_existing_FK_if_using_different_princ var fk = dependentType.GetForeignKeys().Single(foreignKey => foreignKey != existingFk); Assert.NotSame(principalKey, fk.PrincipalKey); Assert.Empty(principalType.GetIndexes()); - Assert.Single(dependentType.GetIndexes()); - Assert.True(fk.DeclaringEntityType.FindIndex(fk.Properties).IsUnique); + + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Single(dependentType.GetIndexes()); + Assert.True(fk.DeclaringEntityType.FindIndex(fk.Properties)!.IsUnique); + } + else + { + Assert.Empty(dependentType.GetIndexes()); + } + Assert.Empty(principalType.GetIndexes()); } @@ -3171,12 +3613,28 @@ public virtual void Creates_index_even_if_covered_by_an_alternate_key() Assert.Empty(principalType.GetForeignKeys()); var fk = dependentType.GetForeignKeys().Single(foreignKey => foreignKey != existingFk); Assert.Empty(principalType.GetIndexes()); - Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); + + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); + } + else + { + Assert.Empty(dependentType.GetIndexes()); + } modelBuilder.Entity().Ignore(t => t.BurgerId2); - Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); - Assert.True(fk.DeclaringEntityType.FindIndex(fk.Properties).IsUnique); + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Equal(dependentType.GetForeignKeys().Count(), dependentType.GetIndexes().Count()); + Assert.True(fk.DeclaringEntityType.FindIndex(fk.Properties)!.IsUnique); + } + else + { + Assert.Empty(dependentType.GetIndexes()); + } + Assert.Empty(principalType.GetIndexes()); } diff --git a/test/EFCore.Specification.Tests/ModelBuilding/ModelBuilderTest.OwnedTypes.cs b/test/EFCore.Specification.Tests/ModelBuilding/ModelBuilderTest.OwnedTypes.cs index a049f3f3603..6c7bcd5ce57 100644 --- a/test/EFCore.Specification.Tests/ModelBuilding/ModelBuilderTest.OwnedTypes.cs +++ b/test/EFCore.Specification.Tests/ModelBuilding/ModelBuilderTest.OwnedTypes.cs @@ -417,8 +417,16 @@ public virtual void Can_configure_owned_type_collection_from_an_owned_type() Assert.Equal(nameof(Order.CustomerId), chainedOwnership.Properties.Single().Name); Assert.Equal(nameof(Order.OrderId), chainedOwned.FindPrimaryKey().Properties.Single().Name); Assert.Single(chainedOwned.GetForeignKeys()); - Assert.Equal(nameof(Order.CustomerId), chainedOwned.GetIndexes().Single().Properties.Single().Name); - Assert.Same(entityBuilder.OwnedEntityType, chainedOwned); + + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Equal(nameof(Order.CustomerId), chainedOwned.GetIndexes().Single().Properties.Single().Name); + Assert.Same(entityBuilder.OwnedEntityType, chainedOwned); + } + else + { + Assert.Empty(chainedOwned.GetIndexes()); + } Assert.Equal(3, model.GetEntityTypes().Count()); } @@ -453,8 +461,17 @@ public virtual void Can_configure_owned_type_collection() Assert.Null(owner.FindProperty("foo")); Assert.Equal(nameof(Order.AnotherCustomerId), owned.FindPrimaryKey().Properties.Single().Name); - Assert.Equal(2, owned.GetIndexes().Count()); - Assert.Equal("CustomerAlternateKey", owned.GetIndexes().First().Properties.Single().Name); + + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Equal(2, owned.GetIndexes().Count()); + Assert.Equal("CustomerAlternateKey", owned.GetIndexes().First().Properties.Single().Name); + } + else + { + Assert.Single(owned.GetIndexes()); + } + Assert.Equal("foo", owned.GetIndexes().Last().Properties.Single().Name); Assert.Equal(PropertyAccessMode.FieldDuringConstruction, owned.GetPropertyAccessMode()); Assert.Equal(ChangeTrackingStrategy.ChangedNotifications, owned.GetChangeTrackingStrategy()); @@ -496,9 +513,18 @@ public virtual void Can_configure_owned_type_collection_using_nested_closure() Assert.Equal("bar", owned.FindAnnotation("foo").Value); Assert.Single(owned.GetForeignKeys()); Assert.Equal("Id", owned.FindPrimaryKey().Properties.Single().Name); - Assert.Equal(2, owned.GetIndexes().Count()); + + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Equal(2, owned.GetIndexes().Count()); + Assert.Equal("DifferentCustomerId", owned.GetIndexes().Last().Properties.Single().Name); + } + else + { + Assert.Single(owned.GetIndexes()); + } + Assert.Equal(nameof(Order.AnotherCustomerId), owned.GetIndexes().First().Properties.Single().Name); - Assert.Equal("DifferentCustomerId", owned.GetIndexes().Last().Properties.Single().Name); Assert.False(owned.FindProperty(nameof(Order.AnotherCustomerId)).IsNullable); Assert.Equal(nameof(Order.Customer), ownership.DependentToPrincipal.Name); } @@ -672,9 +698,18 @@ public virtual void Can_chain_owned_type_collection_configurations() Assert.False(chainedOwnership.IsUnique); Assert.Equal("OrderId", chainedOwnership.Properties.Single().Name); Assert.Equal(nameof(Product.Id), chainedOwned.FindPrimaryKey().Properties.Single().Name); - Assert.Equal( - "OrderId", - chainedOwned.GetIndexes().Single().Properties.Single().Name); + + if (Fixture.ForeignKeysHaveIndexes) + { + Assert.Equal( + "OrderId", + chainedOwned.GetIndexes().Single().Properties.Single().Name); + } + else + { + Assert.Empty(chainedOwned.GetIndexes()); + } + Assert.Equal(nameof(Product.Order), chainedOwnership.DependentToPrincipal.Name); Assert.Equal(4, model.GetEntityTypes().Count()); @@ -1805,7 +1840,7 @@ public virtual void Shared_type_entity_types_with_FK_to_another_entity_works() var bill2 = owner.FindNavigation(nameof(BillingOwner.Bill2)).TargetEntityType; Assert.Equal(2, bill2.GetForeignKeys().Count()); - Assert.Single(bill2.GetIndexes()); + Assert.Equal(Fixture.ForeignKeysHaveIndexes ? 1 : 0, bill2.GetIndexes().Count()); } [ConditionalFact] diff --git a/test/EFCore.Specification.Tests/ModelBuilding/ModelBuilderTest.cs b/test/EFCore.Specification.Tests/ModelBuilding/ModelBuilderTest.cs index b6bec7adf0c..14cbb502477 100644 --- a/test/EFCore.Specification.Tests/ModelBuilding/ModelBuilderTest.cs +++ b/test/EFCore.Specification.Tests/ModelBuilding/ModelBuilderTest.cs @@ -51,6 +51,9 @@ public abstract class ModelBuilderFixtureBase public abstract TestHelpers TestHelpers { get; } public virtual DbContextOptionsBuilder AddOptions(DbContextOptionsBuilder builder) => builder; public virtual IServiceCollection AddServices(IServiceCollection services) => services; + + public virtual bool ForeignKeysHaveIndexes + => true; } public abstract class TestModelBuilder : IInfrastructure diff --git a/test/EFCore.Specification.Tests/ModelBuilding101OneToManyTestBase.cs b/test/EFCore.Specification.Tests/ModelBuilding101OneToManyTestBase.cs index 9f1918e6a33..7c741e00130 100644 --- a/test/EFCore.Specification.Tests/ModelBuilding101OneToManyTestBase.cs +++ b/test/EFCore.Specification.Tests/ModelBuilding101OneToManyTestBase.cs @@ -1305,32 +1305,47 @@ public DbSet Posts => Set(); protected override void OnModelCreating(ModelBuilder modelBuilder) - => modelBuilder.Entity() + { + modelBuilder.Entity() .HasMany(e => e.Posts) .WithOne(e => e.Blog) .HasPrincipalKey(e => e.AlternateId); + + modelBuilder.Entity() + .HasIndex(e => e.BlogId); + } } public class Context1 : Context0 { protected override void OnModelCreating(ModelBuilder modelBuilder) - => modelBuilder.Entity() + { + modelBuilder.Entity() .HasMany(e => e.Posts) .WithOne(e => e.Blog) .HasPrincipalKey(e => e.AlternateId) .HasForeignKey(e => e.BlogId) .IsRequired(); + + modelBuilder.Entity() + .HasIndex(e => e.BlogId); + } } public class Context2 : Context0 { protected override void OnModelCreating(ModelBuilder modelBuilder) - => modelBuilder.Entity() + { + modelBuilder.Entity() .HasOne(e => e.Blog) .WithMany(e => e.Posts) .HasPrincipalKey(e => e.AlternateId) .HasForeignKey(e => e.BlogId) .IsRequired(); + + modelBuilder.Entity() + .HasIndex(e => e.BlogId); + } } public class ContextAnnotated0 : Context101 @@ -1344,6 +1359,7 @@ public class Blog public ICollection Posts { get; } = new List(); } + [Index(nameof(BlogId))] public class Post { public int Id { get; set; } diff --git a/test/EFCore.SqlServer.Tests/Metadata/Conventions/RelationalForeignKeyIndexConventionTest.cs b/test/EFCore.SqlServer.Tests/Metadata/Conventions/RelationalForeignKeyIndexConventionTest.cs new file mode 100644 index 00000000000..9235db2b099 --- /dev/null +++ b/test/EFCore.SqlServer.Tests/Metadata/Conventions/RelationalForeignKeyIndexConventionTest.cs @@ -0,0 +1,187 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Collections; +using Microsoft.EntityFrameworkCore.Metadata.Internal; + +namespace Microsoft.EntityFrameworkCore.Metadata.Conventions; + +public class RelationalForeignKeyIndexConventionTest +{ + [ConditionalFact] + public void Removing_relationship_removes_unused_conventional_index() + { + var modelBuilder = CreateConventionalModelBuilder(); + modelBuilder.Ignore(typeof(SpecialOrder), ConfigurationSource.Explicit); + var principalEntityBuilder = modelBuilder.Entity(typeof(Customer), ConfigurationSource.Explicit); + var derivedPrincipalEntityBuilder = modelBuilder.Entity(typeof(SpecialCustomer), ConfigurationSource.Explicit); + var dependentEntityBuilder = modelBuilder.Entity(typeof(Order), ConfigurationSource.Explicit); + + var relationshipBuilder = dependentEntityBuilder.HasRelationship( + principalEntityBuilder.Metadata, + new[] { dependentEntityBuilder.Property(Order.CustomerIdProperty, ConfigurationSource.Convention).Metadata }, + ConfigurationSource.DataAnnotation); + Assert.NotNull(relationshipBuilder); + + var relationshipBuilder2 = dependentEntityBuilder.HasRelationship( + derivedPrincipalEntityBuilder.Metadata, + new[] { dependentEntityBuilder.Property(Order.CustomerIdProperty, ConfigurationSource.Convention).Metadata }, + ConfigurationSource.DataAnnotation); + Assert.NotNull(relationshipBuilder2); + Assert.NotSame(relationshipBuilder, relationshipBuilder2); + Assert.Single(dependentEntityBuilder.Metadata.GetIndexes()); + + Assert.NotNull( + dependentEntityBuilder.HasNoRelationship(relationshipBuilder.Metadata, ConfigurationSource.DataAnnotation)); + + Assert.Single(dependentEntityBuilder.Metadata.GetIndexes()); + Assert.Single(dependentEntityBuilder.Metadata.GetForeignKeys()); + + Assert.NotNull( + dependentEntityBuilder.HasNoRelationship(relationshipBuilder2.Metadata, ConfigurationSource.DataAnnotation)); + + Assert.Empty(dependentEntityBuilder.Metadata.GetIndexes()); + Assert.Empty(dependentEntityBuilder.Metadata.GetForeignKeys()); + } + + [ConditionalFact] + public void Removing_relationship_does_not_remove_conventional_index_if_in_use() + { + var modelBuilder = CreateConventionalModelBuilder(); + var principalEntityBuilder = modelBuilder.Entity(typeof(Customer), ConfigurationSource.Explicit); + var dependentEntityBuilder = modelBuilder.Entity(typeof(Order), ConfigurationSource.Explicit); + + var relationshipBuilder = dependentEntityBuilder.HasRelationship( + principalEntityBuilder.Metadata, + new[] { dependentEntityBuilder.Property(Order.CustomerIdProperty, ConfigurationSource.Convention).Metadata }, + ConfigurationSource.Convention); + Assert.NotNull(relationshipBuilder); + dependentEntityBuilder.HasIndex(new[] { Order.CustomerIdProperty }, ConfigurationSource.Explicit); + + Assert.NotNull(dependentEntityBuilder.HasNoRelationship(relationshipBuilder.Metadata, ConfigurationSource.DataAnnotation)); + + Assert.Single(dependentEntityBuilder.Metadata.GetIndexes()); + Assert.Equal(Order.CustomerIdProperty.Name, dependentEntityBuilder.Metadata.GetIndexes().First().Properties.First().Name); + Assert.Empty(dependentEntityBuilder.Metadata.GetForeignKeys()); + } + private static TestLogger CreateTestLogger() + => new() { EnabledFor = LogLevel.Warning }; + + private InternalModelBuilder CreateModelBuilder(Model model = null) + => new(model ?? new Model()); + + private InternalModelBuilder CreateConventionalModelBuilder() + => (InternalModelBuilder)SqlServerTestHelpers.Instance.CreateConventionBuilder().GetInfrastructure(); + + public enum MemberType + { + Property, + ComplexProperty, + ServiceProperty, + Navigation, + SkipNavigation + } + + private class Order + { + public static readonly PropertyInfo IdProperty = typeof(Order).GetProperty(nameof(Id)); + public static readonly PropertyInfo CustomerIdProperty = typeof(Order).GetProperty(nameof(CustomerId)); + public static readonly PropertyInfo CustomerUniqueProperty = typeof(Order).GetProperty(nameof(CustomerUnique)); + public static readonly PropertyInfo CustomerProperty = typeof(Order).GetProperty(nameof(Customer)); + public static readonly PropertyInfo ContextProperty = typeof(Order).GetProperty(nameof(Context)); + public static readonly PropertyInfo ProductsProperty = typeof(Order).GetProperty(nameof(Products)); + + public int Id { get; set; } + public int CustomerId { get; set; } + public Guid? CustomerUnique { get; set; } + public Customer Customer { get; set; } + public DbContext Context { get; set; } + public ICollection Products { get; set; } + } + + private class SpecialOrder : Order, IEnumerable + { + public static readonly PropertyInfo SpecialtyProperty = typeof(SpecialOrder).GetProperty("Specialty"); + + public IEnumerator GetEnumerator() + { + yield return this; + } + + IEnumerator IEnumerable.GetEnumerator() + => GetEnumerator(); + + public string Specialty { get; set; } + } + + private class ExtraSpecialOrder : SpecialOrder; + + private class BackOrder : Order; + + private class Customer + { + public static readonly PropertyInfo IdProperty = typeof(Customer).GetProperty(nameof(Id)); + public static readonly PropertyInfo UniqueProperty = typeof(Customer).GetProperty(nameof(Unique)); + public static readonly PropertyInfo OrdersProperty = typeof(Customer).GetProperty(nameof(Orders)); + public static readonly PropertyInfo NotCollectionOrdersProperty = typeof(Customer).GetProperty(nameof(NotCollectionOrders)); + public static readonly PropertyInfo SpecialOrdersProperty = typeof(Customer).GetProperty(nameof(SpecialOrders)); + + public int Id { get; set; } + public Guid Unique { get; set; } + public ICollection Orders { get; set; } + public Order NotCollectionOrders { get; set; } + public ICollection SpecialOrders { get; set; } + internal SpecialCustomer SpecialCustomer { get; set; } + } + + private class SpecialCustomer : Customer + { + internal Customer Customer { get; set; } + } + + private class OrderProduct + { + public static readonly PropertyInfo OrderIdProperty = typeof(OrderProduct).GetProperty(nameof(OrderId)); + public static readonly PropertyInfo ProductIdProperty = typeof(OrderProduct).GetProperty(nameof(ProductId)); + + public int OrderId { get; set; } + public int ProductId { get; set; } + public virtual Order Order { get; set; } + public virtual Product Product { get; set; } + } + + private class Product + { + public static readonly PropertyInfo IdProperty = typeof(Product).GetProperty(nameof(Id)); + + public int Id { get; set; } + + public virtual ICollection Orders { get; set; } + } + + private class SpecialProduct : Product; + + private class ExtraSpecialProduct : SpecialProduct; + + private class Splot + { + public static readonly PropertyInfo SplowedProperty = typeof(Splot).GetProperty("Splowed"); + + public int? Splowed { get; set; } + } + + private class Splow : Splot; + + private class Splod : Splow; + + private class IndexedClass + { + public static readonly string IndexerPropertyName = "Indexer"; + + public object this[string name] + { + get => null; + set { } + } + } +} diff --git a/test/EFCore.Tests/Metadata/Internal/InternalEntityTypeBuilderTest.cs b/test/EFCore.Tests/Metadata/Internal/InternalEntityTypeBuilderTest.cs index 249b828c057..4523843a9cd 100644 --- a/test/EFCore.Tests/Metadata/Internal/InternalEntityTypeBuilderTest.cs +++ b/test/EFCore.Tests/Metadata/Internal/InternalEntityTypeBuilderTest.cs @@ -571,63 +571,6 @@ public void Removing_relationship_removes_unused_contained_shadow_properties() Assert.Empty(dependentEntityBuilder.Metadata.GetForeignKeys()); } - [ConditionalFact] - public void Removing_relationship_removes_unused_conventional_index() - { - var modelBuilder = CreateConventionalModelBuilder(); - modelBuilder.Ignore(typeof(SpecialOrder), ConfigurationSource.Explicit); - var principalEntityBuilder = modelBuilder.Entity(typeof(Customer), ConfigurationSource.Explicit); - var derivedPrincipalEntityBuilder = modelBuilder.Entity(typeof(SpecialCustomer), ConfigurationSource.Explicit); - var dependentEntityBuilder = modelBuilder.Entity(typeof(Order), ConfigurationSource.Explicit); - - var relationshipBuilder = dependentEntityBuilder.HasRelationship( - principalEntityBuilder.Metadata, - new[] { dependentEntityBuilder.Property(Order.CustomerIdProperty, ConfigurationSource.Convention).Metadata }, - ConfigurationSource.DataAnnotation); - Assert.NotNull(relationshipBuilder); - - var relationshipBuilder2 = dependentEntityBuilder.HasRelationship( - derivedPrincipalEntityBuilder.Metadata, - new[] { dependentEntityBuilder.Property(Order.CustomerIdProperty, ConfigurationSource.Convention).Metadata }, - ConfigurationSource.DataAnnotation); - Assert.NotNull(relationshipBuilder2); - Assert.NotSame(relationshipBuilder, relationshipBuilder2); - Assert.Single(dependentEntityBuilder.Metadata.GetIndexes()); - - Assert.NotNull( - dependentEntityBuilder.HasNoRelationship(relationshipBuilder.Metadata, ConfigurationSource.DataAnnotation)); - - Assert.Single(dependentEntityBuilder.Metadata.GetIndexes()); - Assert.Single(dependentEntityBuilder.Metadata.GetForeignKeys()); - - Assert.NotNull( - dependentEntityBuilder.HasNoRelationship(relationshipBuilder2.Metadata, ConfigurationSource.DataAnnotation)); - - Assert.Empty(dependentEntityBuilder.Metadata.GetIndexes()); - Assert.Empty(dependentEntityBuilder.Metadata.GetForeignKeys()); - } - - [ConditionalFact] - public void Removing_relationship_does_not_remove_conventional_index_if_in_use() - { - var modelBuilder = CreateConventionalModelBuilder(); - var principalEntityBuilder = modelBuilder.Entity(typeof(Customer), ConfigurationSource.Explicit); - var dependentEntityBuilder = modelBuilder.Entity(typeof(Order), ConfigurationSource.Explicit); - - var relationshipBuilder = dependentEntityBuilder.HasRelationship( - principalEntityBuilder.Metadata, - new[] { dependentEntityBuilder.Property(Order.CustomerIdProperty, ConfigurationSource.Convention).Metadata }, - ConfigurationSource.Convention); - Assert.NotNull(relationshipBuilder); - dependentEntityBuilder.HasIndex(new[] { Order.CustomerIdProperty }, ConfigurationSource.Explicit); - - Assert.NotNull(dependentEntityBuilder.HasNoRelationship(relationshipBuilder.Metadata, ConfigurationSource.DataAnnotation)); - - Assert.Single(dependentEntityBuilder.Metadata.GetIndexes()); - Assert.Equal(Order.CustomerIdProperty.Name, dependentEntityBuilder.Metadata.GetIndexes().First().Properties.First().Name); - Assert.Empty(dependentEntityBuilder.Metadata.GetForeignKeys()); - } - [ConditionalFact] public void Removing_relationship_does_not_remove_contained_shadow_properties_if_referenced_elsewhere() {