C#枚举到Postgres枚举

问题描述

我当前正在使用postgres枚举

CREATE TYPE http_action_enum AS ENUM ('GET','HEAD','POST','PUT','DELETE','CONNECT','OPTIONS','TRACE','PATCH');
CREATE TABLE IF NOT EXISTS response
(
    id                          UUID                PRIMARY KEY,http_action                 http_action_enum    NOT NULL
);

但是当我使用ef框架插入到postgres数据库时,我一直遇到以下错误

Exception data:
Severity: ERROR
sqlState: 42804
MessageText: column "destination" is of type source_dest_enum but expression is of type integer
Hint: You will need to rewrite or cast the expression.

当我检查响应数据类型时,它实际上是正确的枚举,而不是整数。

Repository.cs

public async Task<Response> InsertRecord(Response response,CancellationToken cancellationToken)
{
      await dBContext.response.AddAsync(response,cancellationToken).ConfigureAwait(true);
      await dBContext.SaveChangesAsync(cancellationToken).ConfigureAwait(true);

      return response;
}

DBContext.cs

      protected override void OnModelCreating(ModelBuilder modelBuilder)
      {
            modelBuilder.HasDefaultSchema("public");
            modelBuilder.HasPostgresEnum<SourceDestinationEnum>();
            modelBuilder.HasPostgresEnum<HttpActionEnum>();

            modelBuilder.Entity<Response>().Property(d => d.RespondedData).HasColumnType("json");

HttpActionEnum.cs

[JsonConverter(typeof(StringEnumConverter))]
    public enum HttpActionEnum
    {
        GET,POST,}

有人遇到过将c#枚举映射到postgres枚举的情况吗?

我尝试转换为枚举,但失败并报错,该列为enum类型,而表达式为text类型。

https://docs.microsoft.com/en-us/ef/core/modeling/value-conversions

DBContext.cs(已更新)

      protected override void OnModelCreating(ModelBuilder modelBuilder)
      {
            modelBuilder.HasDefaultSchema("public");
            modelBuilder.HasPostgresEnum<SourceDestinationEnum>();
            modelBuilder.HasPostgresEnum<HttpActionEnum>();

           modelBuilder.Entity<Response>(entity =>
            {
                entity.Property(e => e.RespondedData).HasColumnType("json");
                entity.Property(e => e.Destination).HasConversion(
                    v => v.ToString(),v => (SourceDestinationEnum)System.Enum.Parse(typeof(SourceDestinationEnum),v));
            });

错误

+       InnerException  {"42804: column \"destination\" is of type source_dest_enum but expression is of type text"}    System.Exception {Npgsql.PostgresException}

解决方法

在此处查看有关postgres枚举的实体框架文章:https://www.npgsql.org/efcore/mapping/enum.html?tabs=tabid-1

即使创建了数据库枚举,Npgsql也必须知道它,尤其是应该映射到它的CLR枚举类型。通过在执行任何EF Core操作之前添加以下代码来完成此操作。一个合适的位置是在DbContext类的静态构造函数中:

static MyDbContext()
    => NpgsqlConnection.GlobalTypeMapper.MapEnum<Mood>();

对于非EF情况,请在此处查看信息:https://www.npgsql.org/doc/types/enums_and_composites.html

,

如果枚举仅需要转换为字符串,则应执行以下操作:

var converter = new EnumToStringConverter<HttpActionEnum>();

modelBuilder
    .Entity<Response>()
    .Property(e => e.RespondedData)
    .HasConversion(converter);