如何通过实体框架为 Oracle 数据库自动生成身份?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5227962/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to automatically generate identity for an Oracle database through Entity framework?
提问by Quan Mai
I'm using Oracle provider for Entity framework (beta), and I'm facing a problem.
我正在将 Oracle 提供程序用于实体框架(测试版),但遇到了问题。
Our tables have Id columns, which are set to be Identity in StoreGeneratedPattern. I thought that EF will automatically do "underlying works", such as create sequences, and get new identity for each record I add to the table. But when I run code to add a new record, such as:
我们的表有 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();
an Exception still throws, which is
一个异常仍然抛出,这是
{"ORA-00001: unique constraint (ADMINMGR.CONSTRAINT_COMMENT) violated"}
(CONSTRAINT_COMMENT is the constrain requires that comment identity must be unique.
{“ORA-00001:违反了唯一约束(ADMINMGR.CONSTRAINT_COMMENT)”}
(CONSTRAINT_COMMENT 是约束要求评论标识必须是唯一的。
How do I solve this?
我该如何解决这个问题?
Thank you very much!
非常感谢!
回答by KristoferA
StoreGeneratedPattern="Identity" simply tells EF that the value will be generated DB-side on insert, and that it shouldn't supply a value in insert statements.
StoreGeneratedPattern="Identity" 只是告诉 EF 该值将在插入时在 DB 端生成,并且不应在插入语句中提供值。
You still need to create a sequence in Oracle:
您仍然需要在 Oracle 中创建一个序列:
create sequence ComplaintIdSequence minvalue 1 maxvalue 9999999 start with 1 increment by 1;
and a trigger to make table inserts use it:
和一个使表插入的触发器使用它:
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;
回答by rocktheartsm4l
Another option would be:
另一种选择是:
Create a sequence the way Alextansc described. Create a stored procedure that uses MySequence.nextval as it's primary key.
按照 Alextansc 描述的方式创建序列。创建一个使用 MySequence.nextval 作为主键的存储过程。
Map 'insert' for this model to your stored procedure and it works!
将此模型的“插入”映射到您的存储过程,它就可以工作了!
I've tested this using database first approach.
我已经使用数据库优先方法对此进行了测试。
Using database first mapping to a stored procedure is pretty simple. Go to your edmx file and right click the model you want to map to a stored procedure. Click "stored procedure mappings." The dialog at the bottom of the page gives you three drop down menus for mapping insert, update, and delete to stored procedures.
使用数据库优先映射到存储过程非常简单。转到您的 edmx 文件并右键单击要映射到存储过程的模型。单击“存储过程映射”。页面底部的对话框为您提供了三个下拉菜单,用于将插入、更新和删除映射到存储过程。
回答by saskcan
I am using Oracle ODP.NET, Managed driver and Entity Framework 6. I created my tables using the code-first approach but wasn't able to add any records due to a null primary key.
我正在使用 Oracle ODP.NET、托管驱动程序和实体框架 6。我使用代码优先方法创建了我的表,但由于主键为空而无法添加任何记录。
The solution was to grant my user both:
'CREATE SEQUENCE'and
'CREATE TRIGGER'
permissions and re-create the schema.
解决方案是授予我的用户:
“CREATE SEQUENCE”和
“CREATE TRIGGER”
权限并重新创建架构。
I realized this after using the -verbose flag in the package management console
在包管理控制台中使用 -verbose 标志后,我意识到了这一点
回答by Dejan
Instead of remember all of this SQL, you could easily do by using Mig#like this:
您可以像这样使用Mig#,而不是记住所有这些 SQL :
var schema = new DbSchema(ConnectionString, DbPlatform.Oracle12c);
schema.Alter(db => db.CreateTable("TableName")
.WithPrimaryKeyColumn("Id", DbType.Int32).AsIdentity()
...);
In this example, the Id
column will have the required trigger and sequence generated by Mig# automatically.
在此示例中,Id
列将具有由 Mig# 自动生成的所需触发器和序列。
回答by Toolkit
Oracle 12c has resolved it
Oracle 12c 已经解决了
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int SomeNumber { get; set; }