One of the cool features of PostgreSQL is in-database enumeration types. With Entity Framework Core 2.1 and the latest Npgsql packages these become (almost) first class types in EF. I say almost because migrations can only create enumerations, any changes have to be manually added to the migrations.

My personal project ended up with multiple EF contexts. No real reason, it just ended up like that. Following the Npgsql documentation I used a class static constructor to map the enumerations to Npgsql

public class MySecondDbContext : DbContext {
    static MySecondDbContext() {
        Npgsql.NpgsqlConnection.GlobalTypeMapper.MapEnum<TestEnum>();
    }

    /* Context implementation */
    protected override void OnModelCreating(ModelBuilder modelBuilder) {
        base.OnModelCreating(modelBuilder);
        modelBuilder.ForNpgsqlUseIdentityByDefaultColumns();
        modelBuilder.ForNpgsqlHasEnum("test_enum", Enum.GetNames(typeof(TestEnum)));
    }
}

However this did not work. I got a message on the lines of column test is of type test_enum but expression is of type integer, which shows the Entity Framework plugin is not correctly mapping the types.

After much digging through the Npgsql source it seemed like the type mapping is constructed statically for the first context created, so as the class constructor has not been run the EF mapper would not take the enum mappings. This also means plugins like the super useful Npgsql.EntityFrameworkCore.PostgreSQL.NodaTime would not map the NodaTime types if only used on the second context, but I was using it on both.

My solution was to move the static constructor to a static method then manually call it in Startup.cs.

class Startup {
    public void ConfigureServices(IServiceCollection services) {
        MySecondDbContext.RegisterTypes();

        services.AddDbContext<MyFirstDbContext>(options =>
            MyFirstDbContext.Configure(options, Configuration.GetConnectionString("DefaultConnection")));
        services.AddDbContext<MySecondDbContext>(options =>
            MySecondDbContext.Configure(options, Configuration.GetConnectionString("SecondConnection")));
    }
}