WPF firebird主键违规

时间:2016-03-20 17:01:05

标签: c# wpf entity-framework firebird

在WPF项目中,我连接到Model的Firebird数据库,然后我尝试将一个项目插入到其中一个声明了主键的表中。

我收到此错误:

  

违反PRIMARY或UNIQUE KEY约束\" PK_ARTI_1 \"桌子上   \" ARTI \"

     

有问题的键值是(\" ID \" = 0)

我的Firebird表有这个DDL:

CREATE TABLE ARTI
(
  ID Integer NOT NULL,
  NAME Varchar(100),
  DESCRIPTION Varchar(200),
  TAX Decimal(10,2) NOT NULL,
  CONSTRAINT PK_ARTI_1 PRIMARY KEY (ID)
);
ALTER TABLE ARTI ADD CONSTRAINT FK_ARTI_1
  FOREIGN KEY (IDTAX) REFERENCES TAX (ID) ON UPDATE NO ACTION ON DELETE NO ACTION;
GRANT DELETE, INSERT, REFERENCES, SELECT, UPDATE
 ON ARTI TO  SYSDBA WITH GRANT OPTION;

我还有一个自动增量ID的触发器(生成器),如下所示:

SET TERM ^ ;
ALTER TRIGGER ARTI_BI ACTIVE
BEFORE INSERT POSITION 0
AS
BEGIN

IF (NEW.ID IS NULL) THEN
  NEW.ID = GEN_ID(GEN_ARTI_ID, 1);

END^
SET TERM ; ^

(这是以不同的方式自动生成的,但我根据其他一些问题/答案删除了一些代码)

如果我尝试通过Entity Framework保存项目,我会收到上述错误。我实际上并不知道如何访问/查看实际的插入表,因为它是在实体框架的幕后完成的,但我绝对不会为ID字段分配任何值。

我添加代码的项目是:

using (ArtEntities context = new ArtEntities())
{
            ARTI art = new ARTI();
            art.NAME = tbname.Text;
            art.DESCRIPTION = tbdesc.Text;
            art.TAX = decimal.Parse(cbTAX.Text);

            context.ARTIs.Add(art);
            context.SaveChanges();

            int idu = art.ID;
}

在最后一行中,我尝试获取插入行的ID的值,但它没有到达那里。它停在SaveChanges(),可能是实体框架正在完成数据库操作。

该表的Model cs文件如下所示:

--- ARTI.cs ---

namespace TestXXX
{
    using System;
    using System.Collections.Generic;

    public partial class ARTI
    {
        public int ID { get; set; }
        public string NAME { get; set; }
        public string DESCRIPTION { get; set; }
        public decimal TAX { get; set; }
    }
}

我还必须提一下,当我尝试向其中添加新项时,该表为空。因此表中没有ID为0的其他值。

我该怎么做才能避免此错误?

在我看来,这可能是某种错误?

新编辑 我已对TRIGGER进行了更改,因此预计ID值为0,如下所示:

SET TERM ^ ;
ALTER TRIGGER ARTI_BI ACTIVE
BEFORE INSERT POSITION 0
AS
DECLARE VARIABLE tmp DECIMAL(18,0);
BEGIN
  IF ((NEW.ID IS NULL)OR(NEW.ID = 0)) THEN
    NEW.ID = GEN_ID(GEN_ARTI_ID, 1);
  ELSE
  BEGIN
    tmp = GEN_ID(GEN_ARTI_ID, 1);
    if (tmp < new.ID) then
      tmp = GEN_ID(GEN_ARTI_ID, new.ID-tmp);
  END
END^
SET TERM ; ^

但现在,当我在

之后进行插入(EF)时
        context.ARTIs.Add(art);
        context.SaveChanges();
        int idu = art.ID;

我使用MessageBox显示我的ID,值始终为ZERO(0)。当我使用FlameRobin检查表时,我可以在ID字段中看到我的新行的不同数字。所以似乎EF确实执行了插入,但是它没有返回实际插入的ID,而是它发送给服务器的那个......或者看起来就像我坐的那样。

如何在SaveChanges()之后获取REAL插入的ID?

1 个答案:

答案 0 :(得分:0)

我相信这个问题的可能解决方案是让我使用UUID而不是ID。这样我就可以在插入之前生成它们,这样我就可以知道UUID而不必在插入后查询表 - 避免了并发问题。