efcore: Upgrade to EFCore 7 Results in Unexpected Index Changes

File a bug

Remember:

  • Please check that the documentation does not explain the behavior you are seeing.
  • Please search in both open and closed issues to check that your bug has not already been filed.

I did a search for the following: All containing indexes must be removed or redefined before the property can be removed. and this did not return anything so I am filing a new issue here to investigate.

Additionally, I also did a search for “index” on this document: https://learn.microsoft.com/en-us/ef/core/what-is-new/ef-core-7.0/breaking-changes

And it does not surface anything obvious to the issue that I am experiencing.

I have attempted to upgrade my model to EfCore 7, using the following command:

dotnet ef dbcontext optimize --output-dir Generated --project Starbeam.Entities.Integration --startup-project Starbeam.Entities.Design

This results in the following error:

The property 'Subject' cannot be removed from entity type 'ResaleOrder' because it is being used in the index {'Subject'} on 'ResaleOrder'. All containing indexes must be removed or redefined before the property can be removed.

Include your code

Ok, so it seems like I need to create a migration to do this? I attempt to do so.

My class looks like this:

[Index(nameof(Subject), IsUnique = true)]
public class ResaleOrder : PurchaseOrder
{
	public ResaleListing Subject { get; set; } = default!;

	public float Royalties { get; set; }
}

So I comment out the [Index(nameof(Subject), IsUnique = true)]. This occurs for other 3 classes throwing this error and after commenting out the indexes I finally get a migration created.

(Note that zero model changes with the exception of the above have been done for my model and worked fantastic in EFCore6)

Within the migration, several indexes + FKs are dropped and recreated – none of which are related to the classes with indexes I commented above. Here is an example

    /// <inheritdoc />
    public partial class RemoveIndexes : Migration
    {
        /// <inheritdoc />
        protected override void Up(MigrationBuilder migrationBuilder)
        {
 // ... omitted for brevity
            migrationBuilder.DropIndex(
                name: "IX_Transaction_SystemDebit_SourceId",
                table: "Transaction");
migrationBuilder.CreateIndex(
                name: "IX_Transaction_SystemDebit_SourceId",
                table: "Transaction",
                column: "SystemDebit_SourceId",
                unique: true,
                filter: "[SourceId] IS NOT NULL");
 // ... omitted for brevity
        }       
    }

Note that filter: "[SourceId] IS NOT NULL" … shouldn’t this be filter: "[SystemDebit_SourceId] IS NOT NULL" ?

Include stack traces

NA this is upgrading from EFCore6 -> 7.

Include verbose output

As this output exposes a good deal of my model I am not comfortable posting this here, but can do so by request to a secure location if necessary. 👍

Include provider and version information

EF Core version: 7 Database provider: . Microsoft.EntityFrameworkCore.SqlServer Target framework: (e.g. .NET 7.0) Operating system: Windows 10 IDE: Microsoft Visual Studio Community 2022 (64-bit) - Preview Version 17.5.0 Preview 1.0

About this issue

  • Original URL
  • State: closed
  • Created 2 years ago
  • Comments: 25 (11 by maintainers)

Most upvoted comments

@Mike-E-angelo You’re right, it’s not OwnsOne in this case, but HasOne has the same problem. That is, [Index(nameof(Subject)... says that Subject is a regular property, but HasOne says that it is a navigation to an entity type. These are incompatible things. IndexAttribute cannot reference a navigation.

Additionally, I am curious about why this works in EFCore6 but not EFCore7.

The model is not valid in either case. The IndexAttribute was likely being ignored in EF Core 6.