mikependon / RepoDB

A hybrid ORM library for .NET.
Apache License 2.0
1.7k stars 125 forks source link

Bug: PostgreSql user defined enum type cannot be written to database #1174

Open jbrezina opened 6 months ago

jbrezina commented 6 months ago

Bug Description

We have a user defined type in the PostgreSQL db.

CREATE TYPE schema.OurType AS ENUM ('Value1', 'Value2', 'Value3');

In c# code we map the enum using

namespace Models
{
  enum OurType { Value1, Value2, Value3 };
}

NpgsqlDataSourceBuilder.MapEnum<Models.OurType>("schema.ourtype", nameTranslator: new NpgsqlNullNameTranslator());

For writing we use the code like this

namespace Models
{
  public class OurModel {
    public int Id { get; set; }
    public OurType Type { get; set; }
  }
}

GlobalConfiguration.Setup().UsePostgreSql();

FluentMapper.Entity<OurModel>().Table("schema.ourmodel");

...

await connection.InsertAsync<OurModel, int>(data, cancellationToken: cancellationToken);

PostgreSqlDbHelper.DynamicHandler changes the NpgsqlParameter.NpgsqlDbType to Unknown for all Enum types. That sets the _npgsqlDbType from null to Unknown. _npgsqlDbType is not null as it should and this leads to wrong invocation chain within NpgsqlParameter.ResolveTypeInfo (AdoSerializerHelpers.GetTypeInfoForWriting -> ... -> TypeInfoCache<TPgTypeId>.GetOrAddInfo ...). I've checked that if I don't set the type to Unknown the code works as expected and correct Oid and type is selected during type resolution.

This change was introduced in fix for #1040, but I'm not sure this is a correct solution and if it is necessary anymore. If it is, I think there should be some check as in RepoDb Compiler.GetPlainTypeToDbParametersCompiledFunction where for enums there is a check if the type IsPostgreSqlUserDefined (maybe the fix should be there?).

Exception Message:

AdoSerializerHelpers.GetTypeInfoForWriting
InvalidCastException
Writing values of 'Models.OurType' is not supported for parameters having DataTypeName 'Unknown'

Library Version:

RepoDb v1.13.1 RepoDb.PostgreSql v1.13.1 Npgsql 8.0.2