You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET Core中ExecuteSqlRawAsync忽略执行策略,如何注入错误处理?

解决EF Core中存储过程调用无法触发执行策略的问题

直接使用Database.ExecuteSqlRawAsync调用存储过程时,确实不会自动纳入EF Core执行策略的错误处理逻辑(重试、日志等),因为这类原始SQL操作默认不会走执行策略的包裹流程。以下是几种可行的解决办法:

1. 手动用执行策略包裹存储过程调用

从DbContext获取执行策略实例,将存储过程的调用逻辑包裹在执行策略的ExecuteAsync方法中,这样就能让执行策略接管错误处理:

var executionStrategy = Database.CreateExecutionStrategy();
await executionStrategy.ExecuteAsync(async () =>
{
    await Database.ExecuteSqlRawAsync("exec dbo.spDoMyVeryTailoredProcedure");
});

2. 封装通用方法减少重复代码

由于你有几十个存储过程调用,可以在DbContext中封装一个通用方法,统一处理执行策略的包裹,避免重复编写相同逻辑:

public async Task ExecuteSpWithStrategyAsync(string spSql, params object[] parameters)
{
    var strategy = Database.CreateExecutionStrategy();
    await strategy.ExecuteAsync(async () =>
    {
        await Database.ExecuteSqlRawAsync(spSql, parameters);
    });
}

之后所有存储过程调用都替换为这个方法:

await ExecuteSpWithStrategyAsync("exec dbo.spDoMyVeryTailoredProcedure");
// 带参数的情况
await ExecuteSpWithStrategyAsync("exec dbo.spAnotherProcedure @Param1 = {0}", paramValue);

3. 确认执行策略已正确配置

确保在配置DbContext时已经启用了SQL Server的重试执行策略,否则上述包裹逻辑不会生效:

services.AddDbContext<YourDbContext>(options =>
    options.UseSqlServer(
        connectionString,
        sqlOpts => sqlOpts.EnableRetryOnFailure(
            maxRetryCount: 5,
            maxRetryDelay: TimeSpan.FromSeconds(30),
            errorNumbersToAdd: null)
    )
);

4. 自定义执行策略(按需使用)

如果默认的重试策略无法满足你的业务需求(比如需要针对特定异常类型重试、添加自定义日志),可以自定义执行策略类,然后在配置DbContext时指定使用:

public class CustomSqlExecutionStrategy : SqlServerRetryingExecutionStrategy
{
    public CustomSqlExecutionStrategy(
        DbContext context,
        int maxRetryCount,
        TimeSpan maxRetryDelay,
        ICollection<int>? errorNumbersToAdd)
        : base(context, maxRetryCount, maxRetryDelay, errorNumbersToAdd)
    {
    }

    protected override bool ShouldRetryOn(Exception exception)
    {
        // 在这里添加自定义的重试判断逻辑
        return base.ShouldRetryOn(exception) || exception is YourCustomException;
    }

    protected override Task<ExecutionResult> ExecuteAsync<TState>(
        Func<DbContext, TState, Task<ExecutionResult>> operation,
        Func<DbContext, TState, Task<ExecutionResult>> verifySucceeded,
        TState state,
        DbContext context,
        CancellationToken cancellationToken)
    {
        // 执行前后可以添加自定义日志逻辑
        return base.ExecuteAsync(operation, verifySucceeded, state, context, cancellationToken);
    }
}

配置时指定使用自定义策略:

services.AddDbContext<YourDbContext>(options =>
    options.UseSqlServer(connectionString)
           .ReplaceService<IExecutionStrategy, CustomSqlExecutionStrategy>());

内容的提问来源于stack exchange,提问作者Nomenator

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 22:47:31