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

.NET 6+EF 6+Oracle中执行策略与连接弹性实现位置及用法咨询

.NET 6 + EF 6 + Oracle 连接弹性与执行策略实践方案

一、连接弹性代码的正确放置位置

EF 6的连接弹性(执行策略)是绑定到DbContext的数据库配置,而非仓储层。仓储层仅负责调用DbContext的业务方法,重试逻辑由EF框架层面统一处理,能确保所有通过该DbContext的数据库操作自动应用重试策略,避免在每个仓储方法中重复编写逻辑。

有两种标准配置方式:

  • 在DbContext的OnConfiguring方法中配置(即你提供的代码所在位置)
  • 在IOC容器注册DbContext时配置(更贴合.NET 6依赖注入的最佳实践)

二、配置Oracle专属执行策略

EF 6默认执行策略主要适配SQL Server,Oracle的连接异常类型不同,需自定义重试逻辑识别Oracle专属错误:

1. 定义Oracle执行策略类

public class OracleExecutionStrategy : DbExecutionStrategy
{
    public OracleExecutionStrategy(int maxRetryCount, TimeSpan maxDelay) 
        : base(maxRetryCount, maxDelay)
    {
    }

    protected override bool ShouldRetryOn(Exception ex)
    {
        // 识别Oracle连接相关异常,匹配常见连接池/超时错误码
        if (ex is OracleException oracleEx)
        {
            var retryErrorCodes = new[] { 12170, 12514, 12541, 12535, 12543, 1033 };
            return retryErrorCodes.Contains(oracleEx.Number);
        }
        // 兼容通用网络超时异常
        return ex is SocketException || ex is TimeoutException;
    }
}

2. 配置到DbContext

方式1:在你提供的OnConfiguring方法中添加

直接修改现有代码,追加执行策略配置:

protected override void OnConfiguring(DbContextOptionsBuilder builder)
{
    base.OnConfiguring(builder.UseOracle(base._connString)
        .EnableSensitiveDataLogging(true)
        // 配置重试策略:最大3次重试,每次间隔2秒
        .UseExecutionStrategy(() => new OracleExecutionStrategy(3, TimeSpan.FromSeconds(2))));
}

方式2:IOC注册时配置(推荐)

如果DbContext在Program.cs中通过DI注册,代码示例:

builder.Services.AddDbContext<YourDbContext>(options =>
{
    options.UseOracle(Configuration.GetConnectionString("OracleConn"))
           .EnableSensitiveDataLogging(true)
           .UseExecutionStrategy(() => new OracleExecutionStrategy(3, TimeSpan.FromSeconds(2)));
});

三、用执行策略执行存储过程

仓储层调用存储过程时,需将操作包裹在执行策略中,确保异常触发重试:

方式1:无返回值存储过程

public class YourRepository
{
    private readonly YourDbContext _dbContext;
    private readonly DbExecutionStrategy _executionStrategy;

    public YourRepository(YourDbContext dbContext)
    {
        _dbContext = dbContext;
        // 从DbContext获取已配置的执行策略
        _executionStrategy = _dbContext.Database.CreateExecutionStrategy();
    }

    public void RunYourStoredProcedure(int param1, string param2)
    {
        _executionStrategy.Execute(() =>
        {
            var sql = "BEGIN YOUR_STORED_PROCEDURE(:p1, :p2); END;";
            _dbContext.Database.ExecuteSqlCommand(sql, 
                new OracleParameter("p1", param1),
                new OracleParameter("p2", param2));
        });
    }
}

方式2:有返回实体的存储过程

public List<YourEntity> GetDataFromProc(int param)
{
    return _executionStrategy.Execute(() =>
    {
        var objectContext = ((IObjectContextAdapter)_dbContext).ObjectContext;
        return objectContext.ExecuteFunction<YourEntity>("YOUR_STORED_PROCEDURE", 
            new ObjectParameter("p_param", param)).ToList();
    });
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 11:52:49