I've been using PostgreSQL as the database for ASP.NET Core 2.0 Identity for a few projects and workshops lately, and I just forgot to do something on a new project which reminded me of something I meant to post about.

The IdentityUser and IdentityRole model classes in Identity have string Id properties, but they don't have a [MaxLength] attribute set; they can't, because the type of the property is a generic parameter. When you use Microsoft.EntityFrameworkCore.SqlServer as the provider, this unbounded string property makes the database column an nvarchar(450) because that's what the provider does with strings that are part of a key.

When you use the PostgreSQL provider, though, the unbounded string gets mapped to the text database type, and a big ol' text blob is not what you want to be using for the indexed primary key columns on your AspNetRoles and AspNetUsers tables.

The fix for this is, fortunately, easy. You just need to use the Fluent API to configure the property in the OnModelCreating override on your ApplicationDbContext. In this particular case, that will look like this:

public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
    public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
        : base(options)
    {
    }

    protected override void OnModelCreating(ModelBuilder builder)
    {
        base.OnModelCreating(builder);

        builder.Entity<ApplicationUser>()
            .Property(u => u.Id)
            .HasMaxLength(450);

        builder.Entity<IdentityRole>()
            .Property(r => r.Id)
            .HasMaxLength(450);

        // These properties are also used in keys
        builder.Entity<IdentityUserLogin<string>>()
            .Property(l => l.LoginProvider)
            .HasMaxLength(450);

        builder.Entity<IdentityUserLogin<string>>()
            .Property(l => l.ProviderKey)
            .HasMaxLength(450);

        builder.Entity<IdentityUserToken<string>>()
            .Property(t => t.LoginProvider)
            .HasMaxLength(450);

        builder.Entity<IdentityUserToken<string>>()
            .Property(t => t.Name)
            .HasMaxLength(450);
    }
}

As you can see, there are some other properties that need the same treatment. As far as I can tell that's the lot.