Я пытаюсь вставить данные с перечислениями через Npg sql. Сначала все работало нормально, но я заметил, что некоторые из моих перечислений не работают. Я сопоставил все свои перечисления 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;
Я приготовил все, чтобы вы могли проверить это самостоятельно, не прилагая больших усилий. При такой настройке я получаю описанную выше ошибку.
Sql:
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();
}
}
}
Есть идеи, что я делаю не так?