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

如何通过WebApplication.CreateBuilder让DataAccess类获取连接字符串

解决方案

1. 改造DataAccess类,支持依赖注入

把静态类改为实例类,通过构造函数注入连接字符串,避免硬编码:

public class DataAccess
{
    private readonly string _connectionString;

    // 构造函数注入连接字符串
    public DataAccess(string connectionString)
    {
        _connectionString = connectionString ?? throw new ArgumentNullException(nameof(connectionString));
    }

    public async Task<DataTable> ExecuteDataTableAsync(string storedProcedure, params SqlParameter[] parameters)
    {
        DataTable dt = new DataTable();

        try
        {
            // 使用注入的连接字符串初始化数据库连接
            using SqlConnection conn = new(_connectionString);
            await conn.OpenAsync(); // 改用异步版的Open方法
            using SqlCommand cmd = new(storedProcedure, conn);
            cmd.CommandTimeout = 3;
            cmd.CommandType = CommandType.StoredProcedure;

            if (parameters != null)
            {
                cmd.Parameters.AddRange(parameters); // 用AddRange简化参数添加逻辑
            }

            using SqlDataAdapter da = new(cmd);
            da.Fill(dt);
        }
        catch (Exception ex)
        {
            LogError(ex);
            throw; // 重新抛出异常,避免吞掉错误信息
        }

        if (dt.Rows.Count == 0)
        {
            throw new Exception("DataTable empty");
        }

        return dt;
    }

    private void LogError(Exception ex)
    {
        // 保留你的日志实现逻辑
        Console.WriteLine($"Error: {ex.Message}");
    }
}

说明:

  • 移除static修饰符,改为实例类,才能通过依赖注入获取连接字符串
  • 删掉不必要的Task.Run,OpenAsync本身已是异步操作,无需额外线程包装
  • 优化参数添加逻辑,用AddRange替代循环
  • 调整空DataTable的判断逻辑,避免冗余的空引用检查

2. 在Program.cs中注册服务并注入连接字符串

在WebApplication构建前,将DataAccess注册到服务容器,同时传入读取到的连接字符串:

var builder = WebApplication.CreateBuilder(args);

// 读取并验证连接字符串
string? connectionString = builder.Configuration.GetConnectionString("P51InvConnection");
if (string.IsNullOrEmpty(connectionString))
{
    throw new InvalidOperationException("Connection string 'P51InvConnection' not found in configuration.");
}

// 注册DataAccess服务,可根据业务需求选择Scoped/Transient/Singleton
builder.Services.AddScoped<DataAccess>(sp => new DataAccess(connectionString));

// 其他服务注册逻辑...

var app = builder.Build();

// 中间件配置...

app.Run();

说明:

  • 先验证连接字符串是否存在,避免后续注入空值引发错误
  • AddScoped表示每个请求实例化一次DataAccess,可根据需求替换为AddTransient(每次获取都实例化)或AddSingleton(全局单例)

3. 在业务代码中注入DataAccess实例

比如在API控制器中使用:

[ApiController]
[Route("[controller]")]
public class InventoryController : ControllerBase
{
    private readonly DataAccess _dataAccess;

    // 构造函数注入DataAccess实例
    public InventoryController(DataAccess dataAccess)
    {
        _dataAccess = dataAccess;
    }

    [HttpGet]
    public async Task<IActionResult> GetInventory()
    {
        var parameters = new SqlParameter[]
        {
            new SqlParameter("@Status", "Active")
        };

        var dataTable = await _dataAccess.ExecuteDataTableAsync("GetInventory", parameters);
        return Ok(dataTable);
    }
}

替代方案:直接注入IConfiguration

如果不想单独传递连接字符串,也可以让DataAccess直接读取配置:

public class DataAccess
{
    private readonly string _connectionString;

    public DataAccess(IConfiguration configuration)
    {
        _connectionString = configuration.GetConnectionString("P51InvConnection") 
            ?? throw new InvalidOperationException("Connection string not found.");
    }

    // 后续方法逻辑同上...
}

此时Program.cs的服务注册更简洁:

builder.Services.AddScoped<DataAccess>();

这种方式无需手动传递连接字符串,但DataAccess会和配置强耦合,灵活性不如直接注入字符串。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 11:43:22