How to implement ambient transaction in Entity Framework Core?

家住魔仙堡 提交于 2020-01-22 15:14:09

问题


I need to realize transaction under two models (using two separated bounded contexts). So code like this:

  using (TransactionScope scope = new TransactionScope())
  {  
       //Operation 1
        using(var context1 = new Context1())
       {
           context1.Add(someCollection1);
           context1.SaveChanges();
       }
       //Operation 2
       using(var context2 = new Context2())
       {
           context2.Add(someCollection2);
           context2.SaveChanges();
       }

       scope.Complete();
   }

return the exception:

An ambient transaction has been detected. Entity Framework Core does not support ambient transactions. See http://go.microsoft.com/fwlink/?LinkId=800142

In Link they advice to use one connection for two context. And use context2 in using block of context1.

But if I use own controller/service for every model:

using (TransactionScope scope = new TransactionScope())
{  
      service1.DoWork();
      service2.DoWork();

       scope.Complete();
 }

How should I implement this? Add connection as parameter in method - seems absurdly. Init service with connection also bad idea.


回答1:


You can use 'contexts' like this:

using (var context1 = new Context1())
{
    using (var transaction = context1.Database.BeginTransaction())
    {
        try
        {
            context1.Add(someCollection1);
            context1.SaveChanges();

            // if we don't have errors - next step 
            using(var context2 = new Context2())
            {
               // second step
               context2.Add(someCollection2);
               context2.SaveChanges();
            }   

            // if all success - commit first step (second step was success completed)
            transaction.Commit();
        }
        catch (Exception)
        {
            // if we have error - rollback first step (second step not be able accepted)
            transaction.Rollback();
        }
    }
}

If you will be use many controllers/services, than you can pass DbConnection into your methods of services with using internal methods for this operation. You must encapsulate logic of low layer.

Init service with connection also bad idea. - may be you right. But you can try init two methods with one connection and single transaction.

See next answers, they can help you:

  • Nested DbContext due to method calls - Entity Framework
  • One transaction with multiple dbcontexts
  • Entity Framework Core - Using Transactions


来源:https://stackoverflow.com/questions/45919011/how-to-implement-ambient-transaction-in-entity-framework-core

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!