如何测试实体框架的执行策略?

时间:2019-01-28 14:13:14

标签: entity-framework-6

我们在下部环境中编码了一个实体框架执行策略。我们如何测试它以表明它确实有效?我们不想在没有任何说法的情况下发布到Prod。我们不会引入新的问题。

1 个答案:

答案 0 :(得分:0)

最简单的方法是使用一些侦听器,您可以在其中引发异常并将该侦听器订阅到dbContext

public class CommandListener
{
    [DiagnosticName("Microsoft.EntityFrameworkCore.Database.Command.CommandExecuting")]
    public void OnCommandExecuting(DbCommand command, DbCommandMethod executeMethod, Guid commandId, Guid connectionId, bool async, DateTimeOffset startTime)
    {
        throw new TimeoutException("Test exception");            
    }

    [DiagnosticName("Microsoft.EntityFrameworkCore.Database.Command.CommandExecuted")]
    public void OnCommandExecuted(object result, bool async)
    {
    }

    [DiagnosticName("Microsoft.EntityFrameworkCore.Database.Command.CommandError")]
    public void OnCommandError(Exception exception, bool async)
    {
    }
}

向监听器订阅dbContext f.i.在Startup.cs

var context = provider.GetService<SomeDbContext>();
var listener = context.GetService<DiagnosticSource>();
(listener as DiagnosticListener).SubscribeWithAdapter(new CommandListener());

由于TimeoutExceptionSqlServerRetryingExecutionStrategy.cs中的暂时异常(如果使用默认重试策略),则您将获得TimeoutException的策略设置,其数量与MaxRetryingCount一样多。最后,由于请求,您必须获得RetryLimitExceededException

您必须在应用程序日志中看到TimeoutException。另外,最好打开事务日志"Microsoft.EntityFrameworkCore.Database.Transaction": "Debug"

我做了什么处理以抛出瞬态异常和调试策略(仅出于目的进行测试和测试)

  1. 我添加了ExectuionStrategyBase.csTestServerRetryingExecutionStrategy.cs。第一个是 ExectuionStrategy.cs,第二个是的克隆 SqlServerRetryingExecutionStrategy.cs
  2. 在Startup.cs中,我设置了重试策略

    strategy services.AddDbContext<SomeDbContext>(options => {options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"), sqlOption => { sqlOption.ExecutionStrategy(dependencies => { return new TestSqlRetryingStrategy( dependencies, settings.SqlMaxRetryCount, settings.SqlMaxRetryDelay, null); });
    });

  3. OnCommandExecuting的{​​{1}}中,我只是检查了一些静态CommandListener.sc变量是否抛出bool,在TimeoutException中则对该变量进行了切换。

因此,我设法在查询的第一次执行时抛出瞬态ExectuionStrategyBase.cs,而在第二次查询时成功执行了瞬态Exception。现在,我考虑了一些长时间运行的事务,并在执行期间在SSCM中终止了该事务的会话。

此外,我发现如果有类似的查询 var users = context.Users.AsNoTracking().ToArrayAsync()执行策略尚未实施,我被坚持下去。这几天我一直在努力,但仍然无计可施。如果将AsNoTracking删除或将ToArrayAsync()替换为FirstAsync()之类的东西,一切都会很好。