kiwijus
kiwijus

Reputation: 1237

EF7 IdentityDbContext migration modifying index

I'm attempting to do multi-tenancy using aspnetcore identity however I'm running into trouble trying to modify the "UserNameIndex" unique index to include the tenantid.

I can see the index I want to modify is the following (this is from Microsoft.AspNetCore.Identity.EntityFrameworkCore/IdentityDbContext.cs)

b.HasIndex(u => u.NormalizedUserName).HasName("UserNameIndex").IsUnique();

Here is an extract from my dbcontext

public class MyContext : IdentityDbContext<Customer, CustomerRole, int>
{
    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);
        modelBuilder.Entity<Customer>().HasIndex(i => new { i.NormalizedUserName, i.TenantId }).HasName("UserNameIndex").IsUnique();
    }
}

When I add a migration this has absolutely no affect - however if I rename the index it creates the migrtation!! Is it not possible to override the index?

Upvotes: 1

Views: 321

Answers (1)

Eric Quist
Eric Quist

Reputation: 51

I have the same problem and the only way I have managed to solve this is to completly override the OnModelCreating method. That is unfortunate, since it is very little of the total configuration that I want to modify.

public class MyContext : IdentityDbContext<Customer, CustomerRole, int>
{
    protected override void OnModelCreating(ModelBuilder builder)
    {
        builder.Entity<Customer>(b =>
        {
            b.HasKey(u => u.Id);
            b.HasIndex(u => new { u.NormalizedUserName, u.TenantId}).HasName("UserNameIndex").IsUnique();
            b.HasIndex(u => new { u.NormalizedEmail, u.TenantId}).HasName("EmailIndex");
            b.ToTable("AspNetUsers");
            b.Property(u => u.ConcurrencyStamp).IsConcurrencyToken();
            b.Property(u => u.UserName).HasMaxLength(256);
            b.Property(u => u.NormalizedUserName).HasMaxLength(256);
            b.Property(u => u.Email).HasMaxLength(256);
            b.Property(u => u.NormalizedEmail).HasMaxLength(256);
            b.HasMany((u => u.Claims)).WithOne().HasForeignKey(uc => uc.UserId).IsRequired();
            b.HasMany((u => u.Logins)).WithOne().HasForeignKey(ul => ul.UserId).IsRequired();
            b.HasMany((u => u.Roles)).WithOne().HasForeignKey(ur => ur.UserId).IsRequired();
        });
        builder.Entity<CustomerRole>(b =>
        {
            b.HasKey(r => r.Id);
            b.HasIndex(r => new { r.NormalizedName, r.TenantId}).HasName("RoleNameIndex");
            b.ToTable("AspNetRoles");
            b.Property(r => r.ConcurrencyStamp).IsConcurrencyToken();
            b.Property(u => u.Name).HasMaxLength(256);
            b.Property(u => u.NormalizedName).HasMaxLength(256);
            b.HasMany(r => r.Users).WithOne().HasForeignKey(ur => ur.RoleId).IsRequired();
            b.HasMany(r => r.Claims).WithOne().HasForeignKey(rc => rc.RoleId).IsRequired();
        });
        builder.Entity<IdentityUserClaim<int>>(b =>
        {
            b.HasKey(uc => uc.Id);
            b.ToTable("AspNetUserClaims");
        });
        builder.Entity<IdentityRoleClaim<int>>(b =>
        {
            b.HasKey(rc => rc.Id);
            b.ToTable("AspNetRoleClaims");
        });
        builder.Entity<IdentityUserRole<int>>(b =>
        {
            b.HasKey(r => new
            {
                r.UserId, r.RoleId
            });
            b.ToTable("AspNetUserRoles");
        });
        builder.Entity<IdentityUserLogin<int>>(b =>
        {
            b.HasKey(l => new
            {
                l.LoginProvider, l.ProviderKey
            });
            b.ToTable("AspNetUserLogins");
        });
        builder.Entity<IdentityUserToken<int>>(b =>
        {
            b.HasKey(l => new
            {
                l.UserId, l.LoginProvider, l.Name
            });
            b.ToTable("AspNetUserTokens");
        });
    }

}

Don't forget to update/re-generate the migrations.

Please notice that I also have roles per tenant, so I have changed the RoleNameIndex too. If you don't want that, just change that line to:

b.HasIndex(r => r.NormalizedName).HasName("RoleNameIndex");

Upvotes: 1

Related Questions