[英]How to insert identity value in Oracle using Entity Framework using a sequence
在 Oracle 数据库中,它的 ID 列定义为数字:
...以及表的相应序列...:
如何确保 ID 列获得序列中的下一个值?
using (var db = new MyOracleDb()){
var user= new User(){ first_name = 'Abe', last_name = 'Lincoln'};
//Do something here with the sequence and set the ID?
db.User.Add(user);
db.SaveChanges();
}
我正在使用最新的 Oracle.ManagedDataAccess 和 Oracle.ManagedDataAccess.EntityFramework + EF6x。
这不是 EF 问题,因为 oracle 中没有自动增量。 您将不得不手动获取序列值,或者创建一个触发器来为您设置它。
为了获得序列值,您有两个选择 - 创建一个存储过程,返回值 - 或创建一个调用原始 SQL 的 .Net 函数(实际上不必在函数中,它只是更简单)这个:
Database.SqlQuery<int>("SELECT SEQ_SOMESEQ.NEXTVAL FROM dual");
我个人对 oracle 函数和 EF 有很多问题,所以我会使用原始 sql。
我创建了一个界面:
public interface IHasSequencer
{
decimal Id { get; set; }
string GetSequenser();
}
然后在我的模型中实现它:
[Table("CLN_CLIENTS")]
public class ClnClient : IHasSequencer
{
public string GetSequenser()
{
return "SEQ_CLN_CLIENTS";
}
[Key, Column("ID")]
public decimal Id { get; set; }
[Column("FIRSTNAME")]
public string FirstName { get; set; }
[Column("LASTNAME")]
public string LastName { get; set; }
[Column("MIDDLENAME")]
public string MiidleName { get; set; }
}
并在我的 DbContext 中添加了一些MAGIC覆盖 SaveChanges() 方法:
public override int SaveChanges()
{
var addedEntries = ChangeTracker.Entries().Where(e => e.State == EntityState.Added);
foreach (DbEntityEntry entry in addedEntries)
{
if (entry.Entity is IHasSequencer)
{
var sequencerEntity = entry.Entity as IHasSequencer;
var nextSeqVal = Database.SqlQuery<Int64>("SELECT " + sequencerEntity.GetSequenser() + ".NEXTVAL FROM DUAL").First();
sequencerEntity.Id = nextSeqVal;
}
}
return base.SaveChanges();
}
就是这样! 现在需要序列器 ID 值的模型必须实现小接口。
仅供参考,使用实体框架,我遇到了独特约束的问题。 对于未来的读者,如果您仍然遇到独特的约束问题。 请确保根据您的要求更改属性“StoreGeneratedPattern”。
对我来说,我正在添加 MAX(ID) + 1 并将 StoreGeneratedPattern 设置为 Identity ,它开始正常工作,但一段时间后通过抛出相同的唯一约束问题破坏了整个程序,当我检查数据库时绝对不是这种情况。 这是大多数开发人员没有注意的事情。
我已将其更改为“无”,因此我可以控制要添加的内容,而不是每隔几天就破坏它的实体框架。 实体框架属性图片
如果您在 Oracle 方面创建触发器,则不必担心您的代码。 它的工作方式就好像它确实有一个身份。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.