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 的内容,我只是浏览了一下,因此以数小时的挫折告终。
我在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 添加类型处理程序,但这并没有解决异常。我找到了
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 的内容,我只是浏览了一下,因此以数小时的挫折告终。