Search code examples
c#entity-frameworkasp.net-identityef-fluent-api

Undo HasIndex in OnModelCreating


I am trying to configure a multi-tenancy application using Identity Framework Core.

I have successfully created a custom ApplicationUser to override IdentityUser with TenantId using instructions here: https://www.scottbrady91.com/ASPNET-Identity/Quick-and-Easy-ASPNET-Identity-Multitenancy (these are instructions are not for Identity Framework Core but they helped).

I am stuck at the point when I am creating the database tables.

protected override void OnModelCreating(ModelBuilder builder)
{
    base.OnModelCreating(builder);
    builder.Entity<Models.User>(entity =>
    {
        entity.HasIndex(a => new { a.NormalizedUserName, a.TenantId }).HasName("UserNameIndex").IsUnique();
    });
}

My intention with this is to replace the UserNameIndex which is defined in base.OnModelCreating() so that it is an index on two columns rather than just NormalizedUsername. But this just results in the error:

The indexes {'NormalizedUserName', 'TenantId'} on 'User' and {'NormalizedUserName'} on 'User' are both mapped to 'Security.AspNetUser.UserNameIndex' but with different columns ({'NormalizedUserName', 'TenantId'} and {'NormalizedUserName'}).

Obviously I want to undo the Index that is created in the base.OnModelCreating() call before I add it in my code, but can't find a method to do that.

Is there a way to remove an Index from ModelBuilder that has been created further up the model creation chain?


Solution

  • I have found a solution with help from https://github.com/aspnet/EntityFrameworkCore/issues/6239

    You can use MetaData.RemoveIndex() to remove the index that already exists

    protected override void OnModelCreating(ModelBuilder builder)
    {
        base.OnModelCreating(builder);
        builder.Entity<Models.User>(entity =>
        {
            // Added these two lines
            var index = b.HasIndex(u => new { u.NormalizedUserName }).Metadata; 
            b.Metadata.RemoveIndex(index.Properties);
    
            entity.HasIndex(a => new { a.NormalizedUserName, a.TenantId }).HasName("UserNameIndex").IsUnique();
        });
    }