c# - npgsql 说枚举未注册
问题描述
我正在尝试通过 Npgsql 插入一些带有枚举的数据。起初,一切正常,但我注意到,我的一些枚举不起作用。我已将所有 c# 枚举映射到 postgres 枚举,但是在尝试使用它们时,其中一些给我以下消息:
CLR 枚举类型 One_More_Enum 使用前必须在 Npgsql 中注册,请参考文档
我想我已经根据文档映射了我的枚举。至少枚举Some_Enum
和Another_Enum
工作都很好。
这是我的代码:
//Enum declaration
public enum Some_Enum
{
[PgName("SOME_VALUE")]
SOME_VALUE,
[PgName("ANOTHER_VALUE")]
ANOTHER_VALUE,
[PgName("ONE_MORE_VALUE")]
ONE_MORE_VALUE
}
public enum Other_Enum
{
[PgName("SOME_VALUE")]
SOME_VALUE,
[PgName("ANOTHER_VALUE")]
ANOTHER_VALUE,
[PgName("ONE_MORE_VALUE")]
ONE_MORE_VALUE
}
public enum One_More_Enum
{
[PgName("SOME_VALUE")]
SOME_VALUE,
[PgName("ANOTHER_VALUE")]
ANOTHER_VALUE,
[PgName("ONE_MORE_VALUE")]
ONE_MORE_VALUE
}
//Register my enums according to the documentation
NpgsqlConnection.GlobalTypeMapper.MapEnum<Some_Enum>("some_enum");
NpgsqlConnection.GlobalTypeMapper.MapEnum<Other_Enum>("other_enum");
NpgsqlConnection.GlobalTypeMapper.MapEnum<One_More_Enum>("one_more_enum");
using (var connection = new Npgsql.NpgsqlConnection(CONNECTION_STRING))
{
connection.Open();
var command = connection.CreateCommand();
command.CommandText = $"INSERT INTO TABLE_A (NAME, SOME_ENUM) VALUES (@NAME, @SOME_ENUM) RETURNING ID";
command.Parameters.AddWithValue("NAME", "Foo Bar");
command.Parameters.AddWithValue("SOME_ENUM", Some_Enum.SOME_VALUE);
var A_id = command.ExecuteScalar(); //Works fine...
command.Parameters.Clear();
command.CommandText = $"INSERT INTO TABLE_B (A_ID, NAME, FOO, BAR, OTHER_ENUM)" +
$"VALUES (@A_ID, @NAME, @FOO, @BAR, @OTHER_ENUM) RETURNING ID";
command.Parameters.AddWithValue("NAME", "Some Name Bla Bla");
command.Parameters.AddWithValue("A_ID", A_id);
command.Parameters.AddWithValue("FOO", false);
command.Parameters.AddWithValue("BAR", false);
command.Parameters.AddWithValue("OTHER_ENUM", Other_Enum.ANOTHER_VALUE);
var B_id = command.ExecuteScalar(); //Works fine
command.Parameters.Clear();
command.CommandText = $"INSERT INTO TABLE_C (B_ID, NAME, ONE_MORE_ENUM) VALUES (@B_ID, @NAME @ONE_MORE_ENUM) RETURNING ID";
command.Parameters.AddWithValue("B_ID", B_id);
command.Parameters.AddWithValue("NAME", "Hey Ho Name");
command.Parameters.AddWithValue("ONE_MORE_ENUM", One_More_Enum.ONE_MORE_VALUE);
var D_id = command.ExecuteScalar(); //!!! Error is thrown here...
}
我在堆栈上发现了这个问题,问题似乎是通过注册枚举而不是全局而是通过连接来解决的(但是问题的发布者认为这并没有解决他的问题(看看他的回答))。我试过这样:
//Register my enums according to the documentation
NpgsqlConnection.GlobalTypeMapper.MapEnum<Some_Enum>("some_enum");
NpgsqlConnection.GlobalTypeMapper.MapEnum<Other_Enum>("other_enum");
//NpgsqlConnection.GlobalTypeMapper.MapEnum<One_More_Enum>("one_more_enum");
using (var connection = new Npgsql.NpgsqlConnection(CONNECTION_STRING))
{
connection.Open();
connection.TypeMapper.MapEnum<One_More_Enum>("one_more_enum");
connection.ReloadTypes();
//...
}
但我得到同样的错误信息......
这是 postgre 中枚举的声明:
CREATE TYPE SOME_ENUM AS ENUM ('SOME_VALUE', 'ANOTHER_VALUE', 'ONE_MORE_VALUE');
ALTER TYPE SOME_ENUM OWNER TO postgres;
CREATE TYPE ANOTHER_ENUM AS ENUM ('SOME_VALUE', 'ANOTHER_VALUE', 'ONE_MORE_VALUE');
ALTER TYPE ANOTHER_ENUM OWNER TO postgres;
CREATE TYPE ONE_MORE_ENUM AS ENUM ('SOME_VALUE', 'ANOTHER_VALUE', 'ONE_MORE_VALUE');
ALTER TYPE ONE_MORE_ENUM OWNER TO postgres;
我已经简化了所有内容,您应该能够自己测试,而无需付出很多努力。通过此设置,我得到了上述错误。
数据:
CREATE TYPE GRABART_MULTIPLIKATOR AS ENUM ('NICHT_MULTIPLIZIEREN', 'ANZAHL_GRABSTELLEN', 'FLAECHE');
ALTER TYPE GRABART_MULTIPLIKATOR OWNER TO postgres;
CREATE TABLE grab_art (
id SERIAL NOT NULL
CONSTRAINT grabart_pkey
PRIMARY KEY,
bezeichnung TEXT,
multiplikator GRABART_MULTIPLIKATOR
);
ALTER TABLE grab_art
OWNER TO postgres;
C#:
class Program
{
const string CONNECTION_STRING = "Server=localhost;Port=5432;Database=my_db;search path=my_demo;User ID=postgres;Password=pw;";
public enum Grabart_Multiplikator
{
[PgName("NICHT_MULTIPLIZIEREN")]
NICHT_MULTIPLIZIEREN,
[PgName("ANZAHL_GRABSTELLEN")]
ANZAHL_GRABSTELLEN,
[PgName("FLAECHE")]
FLAECHE
}
static void Main(string[] args)
{
try
{
NpgsqlConnection.GlobalTypeMapper.MapEnum<Grabart_Multiplikator>("grabart_multiplikator");
using (var connection = new Npgsql.NpgsqlConnection(CONNECTION_STRING))
{
connection.Open();
var command = connection.CreateCommand();
command.CommandText = $"INSERT INTO GRAB_ART (BEZEICHNUNG, MULTIPLIKATOR) VALUES (@BEZEICHNUNG, @MULTIPLIKATOR) RETURNING ID";
command.Parameters.AddWithValue("BEZEICHNUNG", "Neuer Rechtsträger");
command.Parameters.AddWithValue("MULTIPLIKATOR", Grabart_Multiplikator.FLAECHE);
var grabart_id = command.ExecuteScalar();
command.Parameters.Clear();
Console.WriteLine($"Success...");
}
}
catch (Exception e)
{
Console.WriteLine(e);
}
finally
{
Console.WriteLine("Press any key to exit");
Console.ReadKey();
}
}
}
任何想法我做错了什么?
解决方案
我也有这个问题。在不同的模式中具有相同名称的两个枚举。
只需在您的实体配置中设置“schema.enum”:
connection.TypeMapper.MapEnum<One_More_Enum>("schema.one_more_enum");
这个对我有用!
推荐阅读
- python - request.user.is_authenticated 在某些页面上的某些 HTML 上为假,但在视图中则不然
- java - 无法遍历java中链表中的所有元素
- r - 制作分组条形图
- node.js - 发布请求在 node.js express/mongoose 中不起作用
- sql - 尝试更新表时 SQL Developer 中的错误
- settings - Godot引擎输入映射
- java - Lambda 表达式 Java 和 Stream 中的类型错误
- java - 选中复选框时自动添加变量 Android Studio
- nuxt.js - 是否可以收听 NuxtChild 事件
- c++ - 类不扣除其模板参数