【问题标题】:Problem in getting inserted record`s ID Using transaction with Oracle.ManagedDataAccess.EntityFramework使用事务与 Oracle.ManagedDataAccess.EntityFramework 获取插入记录的 ID 时出现问题
【发布时间】:2018-11-14 17:08:39
【问题描述】:

在一个.Net framework 项目中,我使用Visual Studio 添加了一个EF 6.x DbContext Generator,它添加了一个.edmx 文件,其中包含一些.tt 文件;实现了我的database first 结构。

然后我连接到我的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; }
}

另外 Oracle.ManagedDataAccess.EntityFramework Nuget 包已安装。

两个表都以 ID 作为主键,triggersequence 将为 ID 列提供唯一值。

现在我想开始一个事务,在相关的表中插入一些记录:

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(); 
}

问题是在db.USER_TYPES.Add(userType); db.SaveChanges() 之后,我们知道userType.ID 仍将是0(因为我们使用的是oracle)。

网络上有一些解决方案建议通过执行 select max ID 查询来获取最新插入的 ID,或者在插入之前获取下一个序列值。但是当我们使用Transaction时,db中没有实际的记录选择max,或者从序列中选择不准确,模糊。

任何帮助将不胜感激。

【问题讨论】:

  • 你需要配置你的EF模型告诉它数据库正在生成那个值,然后它会在插入后查询它。

标签: c# oracle entity-framework entity-framework-6 oracle-manageddataaccess


【解决方案1】:

感谢David Browne在第一篇文章中的评论并使用this Nuget包,我只是将我的主键列StoredGeneratedPattern更改为Identity > 在我的.edmx 文件中。

通过此更改,实体框架将不会将插入 sql 脚本中的 ID 传递给数据库:

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

而且在插入之后,ID(我的意思是主键列)会自动从数据库中获取,即使我使用transactions

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.
}

【讨论】:

    猜你喜欢
    • 2019-09-01
    • 2013-08-05
    • 2016-11-26
    • 2013-04-11
    • 2015-01-07
    • 1970-01-01
    • 1970-01-01
    • 2011-07-31
    • 2018-11-06
    相关资源
    最近更新 更多