2016-03-20 18 views
0

WPFプロジェクトでは、モデル用のFirebirdデータベースに接続し、プライマリキーが宣言されているテーブルの1つに項目を挿入しようとします。WPFファーバードプライマリキー違反

は、私はこのエラーを取得する:私のFirebirdの表は、このDDLがあり

Violation of PRIMARY or UNIQUE KEY constraint \"PK_ARTI_1\" on table \"ARTI\"

Problematic key value is (\"ID\" = 0)

次のようにも

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 ;^

(これは自動的に別の方法で生成されましたが、他のSO

Entity Frameworkでアイテムを保存しようとすると、上記のエラーが発生します。実際の挿入テーブルへのアクセス/参照方法は実際にはわかりませんが、これはEntity Frameworkの背後で行われるためですが、IDフィールドには値を割り当てません。私が挿入された行の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; 
} 

:コードを追加

私のアイテムはこれです。これはおそらくDB操作がEntity Frameworkによって実行されているSaveChanges()で停止します。

テーブルのモデルの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の値はありません。

このエラーを回避するにはどうすればよいですか?

これは多分何らかのバグのようですね?

NEW EDITそれが0のID値を期待するので、私はこのように、TRIGGERに変更を加えました :私は

後、挿入(EF)を行うと、

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 ;^

が、今

 context.ARTIs.Add(art); 
     context.SaveChanges(); 
     int idu = art.ID; 

IDはMessageBoxを使用して表示され、値は常にゼロ(0)です。 FlameRobinを使用してテーブルをチェックすると、新しい行のIDフィールドに異なる番号が表示されます。だから、EFは挿入を実行しているようですが、実際に挿入されたIDは返されませんが、サーバーに送信したIDは返されません。

SaveChanges()の後にREAL挿入されたIDを取得するにはどうすればよいですか?

+0

IDを指定せずにレコードを手動で(FireRobin)テーブルに挿入しようとしましたが、動作します。なぜWPFからは機能しないのですか – user1137313

+1

'int'のデフォルト値は' 0'なので、 'null'としてトリガーを入力しません。 –

+0

ニースキャッチ@ガートアーノルド。しかし、私は新しいレコードを挿入し、SaveChanges()の後にそれを要求するときに、IDの0とNULLを期待するようにトリガーを変更しました。何か違います。つまり、基本的には、EFを使用してテーブルに新しい行を挿入し、IDの値を割り当てず、挿入が正常になりますが、EFは挿入された値のIDが0であると通知します。実際のIDを挿入するにはどうすればよいですか? – user1137313

答えて

0

この問題の解決策は、IDの代わりにUUIDを使用することだと思います。このようにして、挿入する前にそれらを生成することができ、挿入後にテーブルを照会することなくUUIDを知ることができ、並行処理の問題を避けることができます。