Entity Framework. Возможно ли и рекомендуется ли использовать транзакцию в контексте несколько раз?

Например. у меня такой код

using (AccountingEntities ent = new AccountingEntities())
{
    //just to read record
    var recs = ent.Payments.Where(pp => pp.PaymentId == 123);

    foreach (p in recs)
    {
        if (p.Status == 1)
        {
            using (var dbContextTransaction = ent.Database.BeginTransaction())
            {
                var someotherrecs = ent.SomeTable.Where(s => s.PaymentId == 456);
                foreach (var rec in someotherrecs)
                {
                    rec.Status = 2;
                }
                ent.SaveChanges();
                dbContextTransaction.Commit();
            }
        }
    }
}

Если мне не нужно менять записи, я избегаю запуска транзакции, может быть, в 90% всех случаев. Можно ли делать такие вещи (запуск и завершение нескольких транзакций в одном контексте)?


person alekoo73    schedule 17.05.2019    source источник
comment
SaveChanges делает это автоматически.   -  person Ivan Stoev    schedule 17.05.2019
comment
@IvanStoev Но будет ли это генерировать исключение или пропустить запись изменений?   -  person alekoo73    schedule 17.05.2019
comment
Было бы разумно (возможно), если бы у вас было несколько вызовов SaveChanges в одной транзакции. Иногда это неизбежно.   -  person Gert Arnold    schedule 17.05.2019


Ответы (1)


Как упомянул @Ivan Stoev в комментарии, вам вообще не нужна транзакция. Читать документацию https://docs.microsoft.com/ru-ru/dotnet/api/system.data.objects.objectcontext.savechanges?view=netframework-4.8

и найти там:

SaveChanges работает внутри транзакции.

Итак, в EF есть средство отслеживания изменений, которое отслеживает любые изменения сущностей. Когда вы выполняете SaveChanges, то в одной транзакции все изменения будут зафиксированы или отменены в случае исключения.

Таким образом, ваш код может выглядеть так:

using (AccountingEntities ent = new AccountingEntities())
{
    //just to read record
    var recs = ent.Payments.Where(pp => pp.PaymentId == 123);

    foreach (p in recs)
    {
        if (p.Status == 1)
        {
                var someotherrecs = ent.SomeTable.Where(s => s.PaymentId == 456);
                foreach (var rec in someotherrecs)
                {
                    rec.Status = 2;
                }
                ent.SaveChanges();

        }
    }
}
person Sergey M    schedule 17.05.2019