上下文之间的交易 [英] Transaction between contexts

查看:153
本文介绍了上下文之间的交易的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Entity Framework Core(7)开发控制台应用程序.

I'm developing a Console Application using Entity Framework Core (7).

该应用程序分为3个不同的区域,但是数据库是共享的.我创建了3个不同的 DbContext ,现在我需要在它们之间执行事务.因此,我需要一个原子操作来保存所有更改或不保存任何内容(回滚).

The application is divided into 3 different areas but the database is shared. I created 3 different DbContext and now I need to perform a transaction between all of them. So I need an atomic operation the save all the changes or nothing (rollback).

我知道在实体frameowrk 6中有一个名为 TransactionScope 的类,但是我在EF Core中找不到替代项.

I know that in entity frameowrk 6 there was a class called TransactionScope but I cant find an alterntive in EF Core.

使用以下代码:

public static void Main(string[] args)
    {
        var options = new DbContextOptionsBuilder<DbContext>()
        .UseSqlServer(new SqlConnection("Server=x.x.x.x,1433;Database=test;user id=test;password=test;"))
        .Options;

        var cat = new Cat { Name = "C", Surname = "C", Age = 55 };
        var dog = new Dog { Date = DateTime.Now, Code = 120, FriendId = cat.Id };


        using (var context1 = new DogsContext(options))
        {
            using (var transaction = context1.Database.BeginTransaction())
            {
                try
                {
                    context1.Dogs.Add(dog);
                    context1.SaveChanges();

                    using (var context2 = new CatsContext(options))
                    {
                        context2.Database.UseTransaction(transaction.GetDbTransaction());
                        context2.Cats.Add(cat);
                    }

                    transaction.Commit();
                }
                catch (Exception e)
                {
                    Console.WriteLine(e);
                    transaction.Rollback();
                }
            }
        }
    }

我收到以下错误:

System.InvalidOperationException: ExecuteScalar requires the command to have a transaction when the connection assigned to the co
mmand is in a pending local transaction.  The Transaction property of the command has not been initialized.
   at System.Data.SqlClient.SqlCommand.ValidateCommand(Boolean async, String method)
   at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStrea
m, TaskCompletionSource`1 completion, Int32 timeout, Task& task, Boolean asyncWrite, String method)
   at System.Data.SqlClient.SqlCommand.ExecuteScalar()
   at Microsoft.EntityFrameworkCore.Storage.Internal.RelationalCommand.Execute(IRelationalConnection connection, String executeMe
thod, IReadOnlyDictionary`2 parameterValues, Boolean openConnection, Boolean closeConnection)
   at Microsoft.EntityFrameworkCore.Migrations.HistoryRepository.Exists()
   at Microsoft.EntityFrameworkCore.Migrations.Internal.Migrator.Migrate(String targetMigration)

推荐答案

推荐方法.x.

TransactionScope is not part of Entity Framework. Its part of the System.Transactions namespace. Additionally, TransactionScope is not the recommended approach for handling transactions with Entity Framework 6.x.

使用Entity Framework Core,您只能在多个上下文中为关系数据库共享事务.

With Entity Framework Core you can share a transaction across multiple contexts for relational databases only.

此处的更多信息: https://docs.microsoft.com/zh-cn/ef/core/Saving/transactions

示例(未经测试):

        using (var context1 = new YourContext())
        {
            using (var transaction = context1.Database.BeginTransaction())
            {
                try
                {
                    // your transactional code
                    context1.SaveChanges();

                    using (var context2 = new YourContext())
                    {
                        context2.Database.UseTransaction(transaction.GetDbTransaction());
                        // your transactional code
                    }

                    // Commit transaction if all commands succeed, transaction will auto-rollback when disposed if either commands fails
                    transaction.Commit();
                }
                catch (Exception)
                {
                    // handle exception
                }
            }
        }

这篇关于上下文之间的交易的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆