简体   繁体   English

使用插入的Oracle.ManagedDataAccess.EntityFramework事务获取插入记录的ID时出现问题

[英]Problem in getting inserted record`s ID Using transaction with Oracle.ManagedDataAccess.EntityFramework

In a .Net framework project I added a EF 6.x DbContext Generator using visual studio that adds an .edmx file with some .tt files in it; 在一个.Net framework项目中,我使用Visual Studio添加了一个EF 6.x DbContext Generator ,该文件添加了一个.edmx文件以及一些.tt文件。 that implements my database first structure. 它实现了我的database first结构。

Then I connected to my oracle database and added my tables into it with some models like this: 然后,我连接到oracle数据库,并使用如下模型将表添加到其中:

// DatabaseContext.tt > USER_TYPE.cs
public class USER_TYPE
{
    public int ID { get; set; } // have sequence and insert trigger.
    public string NAME { get; set; }
}

// DatabaseContext.tt > USER.cs
public class USER
{
    public int ID { get; set; } // have sequence and insert trigger.
    public int USER_TYPE_ID { get; set; } // foreign key to USER_TYPES.ID
    public string NAME { get; set; }
}

Also Oracle.ManagedDataAccess.EntityFramework Nuget package is installed. 安装了Oracle.ManagedDataAccess.EntityFramework Nuget软件包。

Both tables have ID as primary key with trigger and sequence that will give the ID column, a unique value. 两个表都将ID作为主键,并带有triggersequence ,这将为ID列提供唯一值。

Now I want to begin a transaction to insert some records in the tables that are related together: 现在,我要开始一个事务,以便在相互关联的表中插入一些记录:

using (var db = new DatabaseContext())
using (var transaction = db.Database.BeginTransaction())
{
    // insert userType
    var userType = new USER_TYPE
    {
        NAME = "admin"
    };

    db.USER_TYPES.Add(userType);
    db.SaveChanges();

    // userType.ID == 0 : true

    // insert user
    var user = new USER
    {
        NAME = "admin user",
        USER_TYPE_ID = userType.ID
    };

    db.USERS.Add(user);
    db.SaveChanges();

    transaction.Commit(); 
}

The problem is after db.USER_TYPES.Add(userType); db.SaveChanges() 问题出在db.USER_TYPES.Add(userType); db.SaveChanges()之后db.USER_TYPES.Add(userType); db.SaveChanges() db.USER_TYPES.Add(userType); db.SaveChanges() we know the userType.ID will remains 0 (because we are using oracle). db.USER_TYPES.Add(userType); db.SaveChanges()我们知道userType.ID将保持为0 (因为我们使用的是oracle)。

There is some solutions in the web that suggest to get the latest inserted ID by executing a select max ID query or get next sequence value before insert. Web中有一些解决方案建议通过执行select max ID查询来获取最新插入的ID,或者在插入之前获取下一个序列值。 but when we use Transaction , there is no actual record in db to select max, or selecting from the sequence is not accurate and is vague. 但是,当我们使用Transaction时 ,db中没有实际记录来选择max,或者从序列中选择是不准确且模糊的。

Any help will be appreciated. 任何帮助将不胜感激。

Thanks to David Browne 's comment in the first post and using this Nuget package, I simply changed the StoredGeneratedPattern to Identity of my primary key column in my .edmx file. 多亏了David Browne在第一篇文章中的评论并使用了 Nuget包,我才将StoredGeneratedPattern更改为.edmx文件中主键列的 Identity

By this change, the Entity Framework will not pass the ID in the insert sql script to the database: 通过此更改,实体框架将不会将插入sql脚本中的ID传递给数据库:

insert into MY_TABLE (NAME) VALUES (@some_value) -- ID is not passed.

And also after insertion, the ID (I mean primary key column) will be obtained automatically from the database, even if I use transactions . 而且在插入之后,即使我使用transactions ,也会自动从数据库中获取ID(我的主键列)。

using (var db = new DatabaseContext())
using (var transaction = db.Database.BeginTransaction())
{
    var userType = new USER_TYPE
    {
        NAME = "admin"
    };

    db.USER_TYPES.Add(userType);
    db.SaveChanges();

    Debug.Assert.IsTrue(userType.ID != 0); // ✔️ will be passed.
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM