【问题标题】:Why does DbContext in EF Core return changed entity after Transaction Rollback为什么 EF Core 中的 DbContext 在事务回滚后返回更改的实体
【发布时间】:2018-09-11 08:59:50
【问题描述】:

我想验证事务是否在出现异常的情况下回滚。下面的方法可能会引发异常。

// method Checkout(user, reduceMoney, addBill)
using (var transaction = _botContext.Database.BeginTransaction())
{
    try
    {
        await FirstDbUpdate(user, reduceMoney);
        await SecondDbUpdate(user, addBill); // potential exception

        transaction.Commit();
    }
    catch (Exception ex)
    {
        // ...
    }
}

为了验证回滚,我编写了这个测试:

[Test]
public async Task Test_TransactionFail_RevertedUserUpdate()
{
    // Arrange user{budget: 10}
    var user = await _userRepository.GetByName("John Doe");
    var reduceMoney = 10m;

    // Act - null causes an exception
    await _service.Checkout(user, reduceMoney, null);  

    // Assert
    var userRetrieved = await _userRepository.GetByName("John Doe");
    Assert.AreEqual(10, userRetrieved.Budget);
}

断言失败,因为用户的预算为 0。也就是说,看起来更改是持久的,但实际上并非如此(这是正确的行为)。

那么问题是为什么 DbContext 会返回未持久化的数据,它是从哪里得到的呢?回滚不应该删除它们吗?

【问题讨论】:

  • 集成测试?你是要进入实际的数据库还是这是你的 DbContext 的某种模拟?您在测试之外看到相同的行为吗?
  • 因为您处于某个上下文实例中,所以 Assert 中的查询将从同一个实例加载,而不是直接查询您的数据库。尝试使用其他实例或重新加载它docs.microsoft.com/en-us/dotnet/api/…
  • @ocrenaka 这是我刚刚用重新加载调用替换第二个查询的解决方案。您能否发表评论,以便我将其标记为解决方案?
  • 当然@rinormaloku

标签: c# entity-framework entity-framework-core


【解决方案1】:

因为您在某个上下文实例中,所以 Assert 中的查询将从同一个实例加载,而不是直接查询您的数据库。

尝试使用其他实例或重新加载它https://docs.microsoft.com/en-us/dotnet/api/microsoft.entityframeworkcore.changetracking.entityentry.reload?view=efcore-2.0

【讨论】:

    猜你喜欢
    • 2020-10-01
    • 1970-01-01
    • 2021-03-19
    • 1970-01-01
    • 2016-05-02
    • 2018-11-30
    • 1970-01-01
    • 2018-02-15
    • 1970-01-01
    相关资源
    最近更新 更多