在具有多个上下文的Entity Framework上使用异步保存更改

时间:2023-02-07 10:10:19

I am using EF 6 with a UoW pattern. I have multiple contexts defined in my UoW since I'm using data from multiple databases. Everything seems to be working correctly except the CommitAsync function I have defined. Here's the code I have:

我正在使用带有UoW模式的EF 6。我在UoW中定义了多个上下文,因为我使用的是来自多个数据库的数据。除了我定义的CommitAsync函数之外,一切似乎都正常工作。这是我的代码:

    public async Task CommitAsync()
    {
        try
        {
            using (var scope = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
            {
                if (_context1 != null)
                    await _context1.SaveChangesAsync();
                if (_context2 != null)
                    await _context2.SaveChangesAsync();

                scope.Complete();
            }
        }
        catch (DbEntityValidationException ex)
        {
            //..
        }
    }

When I run this code saving changes in both contexts I get:

当我运行此代码保存两个上下文中的更改时,我得到:

The transaction manager has disabled its support for remote/network transactions. (Exception from HRESULT: 0x8004D024)

事务管理器已禁用其对远程/网络事务的支持。 (来自HRESULT的异常:0x8004D024)

The await _context2.SaveChangesAsync(); is where the error happens. If I remove the TransactionScope from this function, the code seems to work without error. I am hesitant to remove the scope for multiple contexts.

等待_context2.SaveChangesAsync();是错误发生的地方。如果我从这个函数中删除TransactionScope,代码似乎没有错误。我对于删除多个上下文的范围犹豫不决。

Just in case it'll help, here's the code I use to call this function:

万一它会有所帮助,这是我用来调用这个函数的代码:

        state.Name = "Texas";
        _uow.StateRepository.Update(state);

        user.FirstName = "John";
        _uow.UserRepository.Update(user);

        await _uow.CommitAsync();

Thanks!

1 个解决方案

#1


2  

Using two connections in the same scope requires MSDTC.

在同一范围内使用两个连接需要MSDTC。

You can enable MSDTC to solve this problem. But it does not work with many HA solutions and is slow.

您可以启用MSDTC来解决此问题。但它不适用于许多HA解决方案而且速度很慢。

The only way to avoid using MSDTC is to use the same connection for everything that must be transacted. Since you are using multiple databases that is harder than usual. You need to use SqlConnection.ChangeDatabase or issue the respective SQL to switch between databases on the same connection. The connection must be kept open.

避免使用MSDTC的唯一方法是对必须处理的所有内容使用相同的连接。由于您使用的是比平时更难的多个数据库。您需要使用SqlConnection.ChangeDatabase或发出相应的SQL以在同一连接上的数据库之间切换。连接必须保持打开状态。

Alternatively, you can use three part names for your object references (e.g. DB1.dbo.MyTable).

或者,您可以为对象引用使用三个部件名称(例如DB1.dbo.MyTable)。

There is no other way. Either MSDTC or sharing of the same connection.

没有其他办法。 MSDTC或共享相同的连接。

#1


2  

Using two connections in the same scope requires MSDTC.

在同一范围内使用两个连接需要MSDTC。

You can enable MSDTC to solve this problem. But it does not work with many HA solutions and is slow.

您可以启用MSDTC来解决此问题。但它不适用于许多HA解决方案而且速度很慢。

The only way to avoid using MSDTC is to use the same connection for everything that must be transacted. Since you are using multiple databases that is harder than usual. You need to use SqlConnection.ChangeDatabase or issue the respective SQL to switch between databases on the same connection. The connection must be kept open.

避免使用MSDTC的唯一方法是对必须处理的所有内容使用相同的连接。由于您使用的是比平时更难的多个数据库。您需要使用SqlConnection.ChangeDatabase或发出相应的SQL以在同一连接上的数据库之间切换。连接必须保持打开状态。

Alternatively, you can use three part names for your object references (e.g. DB1.dbo.MyTable).

或者,您可以为对象引用使用三个部件名称(例如DB1.dbo.MyTable)。

There is no other way. Either MSDTC or sharing of the same connection.

没有其他办法。 MSDTC或共享相同的连接。