Npgsql 3.0.0 解析枚举类型失败

Npgsql 3.0.0 Fails to Parse Enumerated Types

我在Postgres中有枚举类型,定义如下:

CREATE TYPE "SomeEnumType" AS ENUM (
    'Val1',
    'Val2'
);

我在 C# 中定义了等效的枚举:

public enum SomeEnumType {
    Val1,
    Val2
}

当我更新到 Npgsql v3.0.0 时,用这种类型的 属性 反序列化 class 失败。例如,我有:

CREATE TABLE Foo (
    Field1 "SomeEnumType" NOT NULL
);

在代码中:

public class Foo {
    public SomeEnumType Field1 { get; set; }
}

当我反序列化我的 class 时,出现错误

Error parsing column 0 (Field1=The field Field1 has a type currently unknown to Npgsql (OID 6965926). You can retrieve it as a string by marking it as unknown, please see the FAQ.)

我尝试向 Dapper 添加类型处理程序,但这并没有解决异常。我找到了 which points to a FAQ page on the Npgsql site。但是,该页面上唯一的答案似乎是:

1) Change the query to explicitly cast unknown types to built-in types
2) Change all Npgsql queries to forgo the use of binary encoding

第一个解决方案使我的查询变得非常复杂,因为真实的表有很多列。例如,使用此解决方案会更改我的所有查询:

SELECT * FROM Foo

收件人:

SELECT Column1, Column2, Column3, Field1::TEXT, Column4 FROM Foo

这显然是一个不可接受的解决方案,因为任何数量的更改(重新排序列、添加列、删除列、更改列类型等)都可能需要更改查询。第二种解决方案更易于维护,但需要将更多数据发送 to/from 服务器,这将导致性能影响。是否有任何其他方法(读作:更易于维护)让 Npgsql v3.0.0 解析枚举类型?

解决方案是在创建任何连接之前注册每个枚举。在我的例子中,这一行被添加到我的数据访问层的静态构造函数 class:

NpgsqlConnection.RegisterEnumGlobally<SomeEnumType>(
    typeof(SomeEnumType).Name);

如果您在 Postgres 中使用不区分大小写的命名(例如,没有引用 Postgres 数据类型),那么您不需要将任何参数传递给 RegisterEnumGlobally,因为默认值是 C# 类型的小写名称。

此回复适用于遇到此问题且上述解决方案无效的任何人。

我遇到了类似的问题。事实证明,对于 NpgsqlConnections,如果您在迁移中创建枚举,则必须重新加载类型。我使用 DpUp 作为我的迁移工具,并将 connection.ReloadTypes() 添加到我的迁移器的末尾。更多关于这里 https://www.npgsql.org/efcore/mapping/enum.html#creating-your-database-enum 的内容,我只是浏览了一下,因此以数小时的挫折告终。