Как использовать транзакции с Entity Framework? - PullRequest
27 голосов
/ 28 июня 2009

Когда у вас есть такой код:

Something something = new Something();
BlahEntities b = new BlahEntities()    
b.AddToSomethingSet(something);
b.SaveChanges();

как выполнить это дополнение внутри транзакции?

Ответы [ 5 ]

55 голосов
/ 28 июня 2009

ObjectContext имеет свойство подключения, которое вы можете использовать для управления транзакциями.

using (var context = new BlahEntities())
using (var tx = context.BeginTransaction())
{
    // do db stuff here...
    tx.Commit();
}

В случае исключения транзакция будет отменена. Поскольку вызов BeginTransaction () требует открытого соединения, имеет смысл заключить вызов BeginTransaction, возможно, в метод расширения.

public static DbTransaction BeginTransaction(this ObjectContext context)
{
    if (context.Connection.State != ConnectionState.Open)
    {
        context.Connection.Open();
    }
    return context.Connection.BeginTransaction();
}

Один сценарий, в котором, как я полагаю, этот подход может быть полезен для TransactionScope, - это когда вам требуется доступ к двум источникам данных и требуется только транзакционный контроль над одним из соединений. Я думаю, что в этом случае TransactionScope перейдет в распределенную транзакцию, которая может не потребоваться.

26 голосов
/ 28 июня 2009

Вы можете поместить свой код в область транзакции

using(TransactionScope scope = new TransactionScope())
{
    // Your code
    scope.Complete(); //  To commit.
}

TransactionScope находится в пространстве имен System.Transactions, которое находится в сборке с тем же именем (которое может потребоваться добавить вручную в ваш проект).

9 голосов
/ 28 июня 2009

Я знаю, что для LINQ to SQL контекст данных создаст транзакцию для SubmitChanges (), если нет существующей внешней транзакции (TransactionScope является "внешней" транзакцией). Я не видел этого документированного для LINQ to Entities, но я видел поведение, позволяющее предположить, что это верно и для Entity Framework.

Так что, пока вы используете один SubmitChanges () (L2SQL) или SaveChanges () (Linq to Entities) для всех связанных изменений, вы должны быть в порядке, не используя TransactionScope. Вам нужен TransactionScope, когда

  1. Сохранение нескольких изменений с несколькими SubmitChanges / SaveChanges для одной транзакции.
  2. Обновление нескольких источников данных в одной транзакции (например, поставщик SQL членства в Linq и ASP.NET).
  3. Вызов других методов, которые могут выполнять свои собственные обновления.

У меня были проблемы с вложенными TransactionScopes. Они должны работать, и работают простые тестовые случаи, но когда я вхожу в рабочий код, «внутренняя» транзакция кажется тем же объектом, что и внешняя транзакция. Симптомы включают в себя ошибки: «транзакция совершена, вы больше не можете использовать эту транзакцию» или «этот объект транзакции уже удален». Ошибки возникают во внешней транзакции после того, как внутренняя транзакция выполнила свою работу.

1 голос
/ 23 ноября 2015
using System.Transactions;

using (TransactionScope scope = new TransactionScope())
{
    try
    {
        using(DataContext contextObject = new DataContext(ConnectionString))
        {
            contextObject.Connection.Open();
            // First SaveChange method.
            contextObject.SaveChanges();

            // Second SaveChange method.
            contextObject.SaveChanges();
            //--continue to nth save changes

            // If all execution successful
            scope.Complete();   
       }
    }
    catch(Exception ex)
    {
        // If any exception is caught, roll back the entire transaction and end the scope.
        scope.Dispose();
    }
    finally
    {
        // Close the opened connection
        if (contextObject.Connection.State == ConnectionState.Open)
        {
            contextObject.Connection.Close();
        }
    }
}

Найдите ссылку ниже для подробного объяснения https://msdn.microsoft.com/en-us/data/dn456843.aspx

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

Во всех версиях Entity Framework всякий раз, когда вы выполняете SaveChanges () для вставки, обновления или удаления базы данных, платформа будет заключать эту операцию в транзакцию. Эта транзакция длится достаточно долго, чтобы выполнить операцию, а затем завершается. При выполнении другой такой операции запускается новая транзакция. Для новейшей версии Entity Framework: 6.0 +

Подробнее здесь: EntityFramework и Transaction

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...