【问题标题】:23502: null value in column "id" violates not-null constraint in postgreSQL23502:“id”列中的空值违反 postgreSQL 中的非空约束
【发布时间】:2020-12-26 09:28:53
【问题描述】:

我用主键创建一个表。

我尝试使用 entityframework6 插入新数据,但会出现 23502 错误。

但我在插入之前将默认值添加到列中。

我不明白为什么会出现这个错误。

表 DDL:

CREATE TABLE ERRORLOG(
id numeric NOT NULL,
message varchar(50) NULL,
CONSTRAINT pterrorlog_pk PRIMARY KEY (id)
);

型号:

public partial class ERRORLOG
{
    [Key]
    [Column(Order = 0)]
    public long ID { get; set; } = DateTimeOffset.Now.ToUnixTimeMilliseconds();
    public string MESSAGE { get; set; }
}

功能:

using (DbContext Db as new DbContext)
using (TransactionScope transactionScope = new TransactionScope())
{
    ERRORLOG iLog = new ERRORLOG();
    iLog.MESSAGE = Message;
    Db.ERRORLOG.Add(iLog);
    Db.SaveChanges(); //Get 23502 error
}

这里是插入脚本,好像没有插入id,这是为什么呢?

INSERT INTO "pterrorlog"("message") VALUES (@p_0) RETURNING "id"

编辑:

在模型上添加此脚本后,它现在可以正常工作了。

public partial class ERRORLOG
{
  [Key]
  [DatabaseGenerated(DatabaseGeneratedOption.None)]
  public long ID { get; set; } = DateTimeOffset.Now.ToUnixTimeMilliseconds();
  public string MESSAGE { get; set; }
}

【问题讨论】:

  • 错误信息很清楚。您正在尝试将NULL 插入到非空列id。也请显示您的插入语句。
  • @ArunPalanisamy 我更新了语句,好像没有插入 id 列,这是为什么呢?
  • 我可以看到您没有将任何值传递给 id。它是一个自动增量列吗?
  • @ArunPalanisamy 我使用这个脚本来设置它的值:public long ID { get;放; } = DateTimeOffset.Now.ToUnixTimeMilliseconds();

标签: postgresql entity-framework


【解决方案1】:

您可以使用 PGAdmin 来分析 EF 实际尝试在 SaveChanges 上执行的 SQL。 C# 区分大小写,而 Postgres 默认为小写。如果我记得 NPGSQL 将使用双引号格式化所有 EF SQL 查询,因此如果您的实体使用 ID 等属性声明,它将生成像 INSERT INTO "ERRORLOG" ( "ID", "MESSAGE" ) VALUES ( ... ) 这样的语句,因此不会设置名为“id”的列。

如果您希望您的实体使用与 DB 不同的大小写,并让 Postgres 使用小写,那么我建议使用 [Column] 属性来重命名列:

public partial class ERRORLOG
{
    [Key, Column(Name = "id")]
    public long ID { get; set; } = DateTimeOffset.Now.ToUnixTimeMilliseconds();
    [Column(Name = "message")]
    public string MESSAGE { get; set; }
}

另一个细节是 Column 属性上的 Order 仅在处理复合键时才需要,例如 PK 由两列或更多列组成的多对多连接表。普通的单值 PK 不需要它。

如果这不是原因,检查 PGAdmin 中的插入语句应该会给你一个线索 NPGSQL / EF 正在尝试执行什么。

【讨论】:

    【解决方案2】:

    看起来实体框架会自动向列插入值。 在我添加脚本以防止此问题后,它现在可以正常工作了。

    [DatabaseGenerated(DatabaseGeneratedOption.None)]
    

    模特想要:

    public partial class ERRORLOG
    {
      [Key]
      [DatabaseGenerated(DatabaseGeneratedOption.None)]
      public long ID { get; set; } = DateTimeOffset.Now.ToUnixTimeMilliseconds();
      public string MESSAGE { get; set; }
    }
    

    【讨论】:

      猜你喜欢
      • 2019-08-08
      • 2020-03-15
      • 1970-01-01
      • 2021-08-06
      • 2021-01-08
      • 1970-01-01
      • 2021-11-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多