在具有多个上下文的实体框架上使用异步保存更改

本文关键字:框架 保存更改 异步 实体 上下文 | 更新日期: 2023-09-27 18:07:54

我使用的是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)
        {
            //..
        }
    }

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

事务管理器已禁用对远程/网络事务的支持。(Exception from HRESULT: 0x8004D024)

> await _context2.SaveChangesAsync();是错误发生的地方。如果我从这个函数中删除TransactionScope,代码似乎可以正常工作。我很犹豫是否要删除多个上下文的作用域。

下面是我用来调用这个函数的代码:
        state.Name = "Texas";
        _uow.StateRepository.Update(state);
        user.FirstName = "John";
        _uow.UserRepository.Update(user);
        await _uow.CommitAsync();

谢谢!

在具有多个上下文的实体框架上使用异步保存更改

使用同一作用域内的两个连接需要MSDTC。

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

避免使用MSDTC的唯一方法是对必须处理的所有事务使用相同的连接。由于您正在使用多个数据库,这比通常更难。您需要使用SqlConnection.ChangeDatabase或发出相应的SQL在同一连接上的数据库之间切换。连接必须保持打开。

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

别无他法。MSDTC或共享同一连接