我有一张存储被拒绝合同提案的表格。
CREATE TABLE "STATUS_CONTRATO" (
"STC_ID" NUMBER NOT NULL,
"CTB_CONTRATO" NUMBER NOT NULL,
"STC_DATA" DATE NOT NULL,
"STC_OBSERVACAO" VARCHAR2(200) NOT NULL,
CONSTRAINT "STATUS_CONTRATO_PK"
PRIMARY KEY ( "STC_ID")
ENABLE
VALIDATE,
CONSTRAINT "FK_CONTRATO"
FOREIGN KEY ( "CTB_CONTRATO")
REFERENCES "CONTRATO" ( CTB_CONTRATO)
ON DELETE SET NULL
ENABLE
VALIDATE)
;
(由Visual Studio 2010生成的脚本)
此表有一个简单的触发器,其中设置了STC_ID
的值:
TRIGGER "STATUS_CONTRATO_TRIGGER1"
BEFORE
INSERT
ON "STATUS_CONTRATO"
FOR EACH ROW
when (new.STC_ID = 0)
DECLARE
BEGIN
SELECT SEQ_STATUS_ID.NEXTVAL INTO :NEW.STC_ID FROM DUAL;
END;
SEQ_STATUS_ID
是一个简单的序列。
这是我的问题:
我可以在VS2010查询窗口中成功执行此插入:
insert into myschema.STATUS_CONTRATO s(
s.STC_ID, s.CTB_CONTRATO, s.STC_DATA, s.STC_OBSERVACAO
)values(
0, 10, SYSDATE, 'Inserting by hand works'
);
但是,当我尝试使用EF插入时,我遇到了这个例外:
System.Data.UpdateException: An error occurred while updating the entries.
See the inner exception for details. ---> Oracle.DataAccess.Client.OracleException:
ORA-01400: cannot insert NULL into ("MYSCHEMA"."STATUS_CONTRATO"."STC_ID")
ORA-06512: at line 4
我正在使用此代码插入
STATUS_CONTRATO statusContrato = new STATUS_CONTRATO() {
STC_ID = 0,
CTB_CONTRATO = codContrato,
STC_DATA = DateTime.Today,
STC_OBSERVACAO = observacao
};
ent.STATUS_CONTRATO.AddObject(statusContrato);
ent.SaveChanges();
我正在使用VS2010,Oracle 11g(CentOS服务器),ODP.NET客户端11.2.0.3.0生产版,.NET Framework 4.0,EF 4。
答案 0 :(得分:4)
请检查:http://www.oracle.com/technetwork/issue-archive/2011/11-sep/o51odt-453447.html
特别是“触发器和序列”部分
从“工具”菜单中,选择“运行SQL Plus脚本”。浏览到 在解压缩代码和脚本的位置,选择 triggers.sql脚本,从列表中选择HR连接,然后单击 跑。脚本创建的INSERTEMPLOYEES触发器生成一个新的 每当为该值传入NULL时,EMPLOYEE_ID的序列........
答案 1 :(得分:1)
您的代码有效,但
的问题除外ent.UNV_STATUS_CONTRATO.AddObject(statusContrato);
UNV_STATUS_CONTRATO
是另一张桌子吗?为什么不是
ent.STATUS_CONTRATO.AddObject(statusContrato);
这应该可以正常工作。
但是,在保存更改之前,您可能会发现最好从代码中获取序列值并将其应用于内存中的ID列。所以像这样:
public static int GetSequenceNextVal()
{
using (YourEntities entities = new YourEntities ())
{
var sql = "select myschema.SEQ_STATUS_ID.NEXTVAL from dual";
var qry = entities.ExecuteStoreQuery<decimal>(sql);
return (int)qry.First();
}
}
然后在SaveChanges()
之前调用该方法。
就个人而言,我更喜欢以这种方式处理它,以便我的内存中实体也具有正确的ID,而不是只有0,或者必须立即查询,等等。
此外,触发器和序列下描述的here方法可以将实体的PK连接到一个序列。
答案 2 :(得分:0)
您需要在EF Mapping中指定数据库不会为您生成密钥,EF应使用您提供的密钥...
在以下主题中查看我的帖子: https://stackoverflow.com/a/18635325/1712367