Проблема в получении идентификатора вставленной записи при использовании транзакции с Oracle.ManagedDataAccess.EntityFramework - PullRequest
0 голосов
/ 14 ноября 2018

В проекте .Net framework я добавил EF 6.x DbContext Generator с использованием Visual Studio, который добавляет файл .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 в качестве первичного ключа с trigger и sequence, что даст столбцу 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 (потому что мы используем оракула).

В Интернете есть некоторые решения, которые предлагают получить последний вставленный идентификатор, выполнив запрос на выбор максимального идентификатора или получить следующее значение последовательности перед вставкой.но когда мы используем Транзакция , нет фактической записи в дБ, чтобы выбрать макс, или выбор из последовательности не точный и расплывчатый.

Любая помощь будет оценена.

1 Ответ

0 голосов
/ 17 ноября 2018

Благодаря комментарию Дэвида Брауна в первом посте и использованию этого пакета Nuget я просто изменил StoredGeneratedPattern на Identity моего столбец первичного ключа в моем .edmx файле.

В результате этого изменения Entity Framework не будет передавать идентификатор в сценарии вставки SQL в базу данных:

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

А также после вставки идентификатор (я имею в виду столбец первичного ключа) будет автоматически получен из базы данных, даже если я использую 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.
}
...