2011-03-08 39 views
11

我正在使用實體框架(測試版)的Oracle提供程序,而且我正面臨一個問題。如何通過實體框架爲Oracle數據庫自動生成標識?

我們的表具有Id列,它們在StoreGeneratedPattern中設置爲Identity。我認爲EF會自動完成「底層工作」,比如創建序列,併爲添加到表格中的每條記錄獲取新的身份。但是,當我運行代碼中添加一個新的記錄,如:

var comment = new Comment 
{ 
    ComplaintId = _currentComplaintId, 
    Content = CommentContent.Text, 
    CreatedBy = CurrentUser.UserID, 
    CreatedDate = DateTime.Now 
}; 

context.Comments.AddObject(comment); 
context.SaveChanges(); 

的異常還是拋出,這是

{ 「ORA-00001:唯一約束(ADMINMGR.CONSTRAINT_COMMENT) 違反」 }

(CONSTRAINT_COMMENT是約束要求評論的身份 必須是唯一的。

我如何解決這個問題?

非常感謝!

+0

http://stackoverflow.com/questions/8232997/generate-identity-for-an-oracle-database-through-entity-framework-using-an-exisi/19684494#19684494 –

回答

15

StoreGeneratedPattern =「Identity」只是告訴EF該值將在插入時生成DB端,並且它不應該在插入語句中提供一個值。

你仍然需要在Oracle中創建一個序列:

create sequence ComplaintIdSequence minvalue 1 maxvalue 9999999 start with 1 increment by 1;

和觸發,使表插入使用它:

create or replace trigger CommplaintIdTrigger 
before insert on comment for each row 
begin 
    if :new.ComplaintId is null then select ComplaintIdSequence.nextval into :new.ComplaintId from dual; 
    endif; 
end;
+1

謝謝你的回答,但我仍然無法相信Oracle只是不會自動執行此操作。( – Vimvq1987

+0

Oracle應該絕對*不會自動執行這些操作(因爲它可以*做的是比你想象的更靈活)你的框架是理解(和隱藏)數據庫平臺之間差異的工作 –

+2

我沒有說Oracle應該在它的數據庫中完成它,但是它肯定應該在它的提供者(「框架「 – Vimvq1987

0

另一種選擇是:

創建序列Alextansc描述的方式。 創建一個使用MySequence.nextval作爲主鍵的存儲過程。

將此模型的'插入'映射到您的存儲過程,它的工作原理!

我已經使用數據庫第一種方法測試了這一點。

使用數據庫優先映射到存儲過程非常簡單。轉到您的edmx文件並右鍵單擊要映射到存儲過程的模型。點擊「存儲過程映射」。頁面底部的對話框爲您提供了三個下拉菜單,用於將插入,更新和刪除映射到存儲過程。

0

我正在使用Oracle ODP.NET,託管驅動程序和實體框架6.我使用代碼優先的方法創建了我的表,但由於空主鍵而無法添加任何記錄。

的解決方案是授予我的用戶都:
'CREATE SEQUENCE'
'CREATE TRIGGER'
權限,並重新創建模式。

我在包管理控制檯中使用-verbose標誌後,意識到這

0

而不是記不住所有SQL的,你可以很容易地通過使用Mig#這樣做:

 var schema = new DbSchema(ConnectionString, DbPlatform.Oracle12c); 
     schema.Alter(db => db.CreateTable("TableName") 
      .WithPrimaryKeyColumn("Id", DbType.Int32).AsIdentity() 
      ...); 

在這個例子中,Id列將自動生成Mig#生成的所需觸發器和序列。

+0

任何人做到了這一點? – Worthy7

0

甲骨文12C已經解決了它

[DatabaseGenerated(DatabaseGeneratedOption.Identity)] 
public int SomeNumber { get; set; } 
相關問題