Skip to content

NpgsqlDataSourceBuilder MapEnum doesn't work, Unable to cast object of type 'System.Int32' to type 'System.Enum' #2853

@Kaitbh

Description

@Kaitbh

I have upgraded the package to 7.0.4 and using dotnet ef 7.0.10, followed documentation to map CLR type properly.
I'm also using dotnet ef dbcontext scaffold to generate the model and dbcontext (DB First). And using partial class to extend the enum property of the entity.

// IServiceCollection Extension
public static void AddMyDbContext(this IServiceCollection serviceCollection, string connectionString)
{
    var dsBuilder = new NpgsqlDataSourceBuilder(connectionString);
        
    // Map enum type (This works)
    // NpgsqlConnection.GlobalTypeMapper.MapEnum<TransactionFlow>();
    
    // This is not working
    dsBuilder.MapEnum<TransactionFlow>();

    var dataSource = dsBuilder.Build();

    serviceCollection.AddDbContext<MyDbContext>(opt =>
    {
        opt.UseNpgsql(dataSource);
        opt.EnableDetailedErrors();
    });
}

// enum TransactionFlow
public enum TransactionFlow
{
    [PgName("IN")]
    IN, 
    [PgName("OUT")]
    OUT
}

// partial class BankTransactionType
public partial class BankTransactionType
{
    [Column("transaction_flow")]
    public TransactionFlow TransactionFlow { get; set; }
}

// partial class DbContext
partial void OnModelCreatingPartial(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<BankTransactionType>(entity =>
    {
        entity.Property(e => e.TransactionFlow);
    });
}

// class DbContext (generated code)
public virtual DbSet<BankTransactionType> BankTransactionTypes { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder
        .HasPostgresEnum("transaction_flow", new[] { "IN", "OUT" });

    OnModelCreatingPartial(modelBuilder);
}
var query = _context.BankTransactionTypes.AsQueryable();
var result = await query.ToListAsync(); // <-- throws error

Error detail:

System.InvalidOperationException: An error occurred while reading a database value for property 'BankTransactionType.TransactionFlow'. The expected type was 'Kaitek.ProjectG.DAL.Enums.TransactionFlow' but the actual value was of type 'System.String'.
 ---> System.InvalidCastException: Unable to cast object of type 'System.Int32' to type 'System.Enum'.
   at Npgsql.Internal.TypeHandlers.UnmappedEnumHandler.CreateTypeRecord(Type type, INpgsqlNameTranslator nameTranslator)
   at Npgsql.Internal.TypeHandlers.UnmappedEnumHandler.<>c.<GetTypeRecord>b__11_0(Type t, INpgsqlNameTranslator translator)
   at System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd[TArg](TKey key, Func`3 valueFactory, TArg factoryArgument)
   at Npgsql.Internal.TypeHandlers.UnmappedEnumHandler.GetTypeRecord(Type type)
   at Npgsql.Internal.TypeHandlers.UnmappedEnumHandler.ReadCustom[TAny](NpgsqlReadBuffer buf, Int32 len, Boolean async, FieldDescription fieldDescription)
   at Npgsql.NpgsqlDataReader.GetFieldValue[T](Int32 ordinal)
   at Npgsql.NpgsqlDataReader.GetInt32(Int32 ordinal)
   at lambda_method182(Closure, QueryContext, DbDataReader, ResultContext, SingleQueryResultCoordinator)
   --- End of inner exception stack trace ---
   at lambda_method182(Closure, QueryContext, DbDataReader, ResultContext, SingleQueryResultCoordinator)
   at Microsoft.EntityFrameworkCore.Query.Internal.SingleQueryingEnumerable`1.AsyncEnumerator.MoveNextAsync()
   at Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.ToListAsync[TSource](IQueryable`1 source, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.ToListAsync[TSource](IQueryable`1 source, CancellationToken cancellationToken)
   ...

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions