忽略TransactionScope以进行特定查询

Joe*_*nos 26 c# entity-framework transactions transactionscope entity-framework-5

我正在寻找一种在TransactionScope处于活动状态时执行查询的方法,并忽略TransactionScope - 基本上,我想执行此特定查询,无论如何.

我使用EF代码优先,以及应用程序的设计方式,一个新的数据上下文贯穿单个呼叫多次打开,每一个都有自己的变化,所有这些都包含在一个单一的TransactionScope,这已经内Complete()称为最后假设没有失败.在上下文中我们已经重写,SaveChanges以便如果发生任何异常base.SaveChanges(),我们可以捕获它并在回滚事务之前登录到数据库.

由于在SaveChanges事务内部发生,因此记录显然不会发生,因为它属于与原始调用相同的事务.我试图完全忽略TransactionScope的日志代码.

这是一些精简代码:

// From the context
public override int SaveChanges() {
    try {
        return base.SaveChanges();
    } catch (Exception ex) {

        // Writes to the log table - I want this to run no matter what
        LogRepo.Log(/*stuff to log from the context*/);

        throw;
    }
}

// Inside the business logic
public void DoSomething() {
    try {
        using (var scope = new TransactionScope()) {

            using (var context = new FooContext()) {
                // Do something
                context.SaveChanges();
            }
            using (var context = new FooContext()) {
                // Do something else
                context.SaveChanges();
            }

            scope.Complete();
        }
    } catch (Exception ex) {
        // scope.Complete is never called, so the transaction is rolled back
    }
}
Run Code Online (Sandbox Code Playgroud)

我尝试使用常规ADO.NET而不是EF来进行日志记录,但结果仍然相同 - 它也会回滚.

我需要在内部发生错误处理SaveChanges,因为我正在记录的是正在保存的实体的状态 - 所以我不能轻易地将记录移动到其他地方.我可以在内部构建消息SaveChanges catch,并抛出它并DoSomething catch记录它,但是有很多DoSomething方法,我宁愿在一个地方处理这个问题.

小智 37

如果在启用了suppress选项的情况下将日志调用包装在另一个事务范围内,则不会使用事务范围.

public override int SaveChanges() {
    try {
        return base.SaveChanges();
    } catch (Exception ex) {
        using (var scope = new TransactionScope(TransactionScopeOption.Suppress)) {
            LogRepo.Log(message); // stuff to log from the context
        }

        throw;
    }
}
Run Code Online (Sandbox Code Playgroud)