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

在ASP.NET Core中实现ADO连接及调用数据库存储过程

在ASP.NET Core中使用ADO.NET调用存储过程的实现方案

我明白你习惯用原生ADO.NET的方式来调用存储过程,在ASP.NET Core里我们可以调整一下实现方式,既保留你熟悉的写法,又符合Core的最佳实践,下面是具体的实现方案:

核心调整点说明

首先要注意,ASP.NET Core中不再推荐直接使用ConfigurationManager来获取连接字符串,而是通过依赖注入的IConfiguration来读取配置,同时我们需要优化连接的生命周期管理,避免资源泄漏。

完整实现代码

1. 注册数据访问服务(.NET 6+ Program.cs示例)

首先在项目的入口文件里,把你的数据访问类注册为依赖注入服务:

var builder = WebApplication.CreateBuilder(args);

// 注册数据访问服务,Scoped生命周期适合大多数Web场景
builder.Services.AddScoped<IEmployeeRepository, EmployeeRepository>();

// 其他服务注册...

var app = builder.Build();

// 中间件配置...

app.Run();

2. 数据访问类实现

这里我们实现一个符合你偏好的存储过程调用逻辑,同时适配ASP.NET Core的设计:

// 定义接口,便于解耦和测试
public interface IEmployeeRepository
{
    int Insert(Employee employee);
}

public class EmployeeRepository : IEmployeeRepository
{
    private readonly IConfiguration _configuration;

    // 通过构造函数注入IConfiguration,获取连接字符串
    public EmployeeRepository(IConfiguration configuration)
    {
        _configuration = configuration;
    }

    public int Insert(Employee employee)
    {
        var result = 0;

        // 推荐在方法内部创建SqlConnection,用using块自动管理资源
        using var dbConnection = new SqlConnection(_configuration.GetConnectionString("DbConnection"));
        using var cmd = new SqlCommand("Sp_Insert", dbConnection)
        {
            CommandType = CommandType.StoredProcedure
        };

        // 添加存储过程参数,推荐明确指定类型和长度,避免类型推断问题
        cmd.Parameters.Add("@FirstName", SqlDbType.NVarChar, 50).Value = employee.FirstName;
        cmd.Parameters.Add("@LastName", SqlDbType.NVarChar, 50).Value = employee.LastName;
        // 根据你的存储过程需求添加其他参数,比如@Age、@DepartmentId等
        // 如果有输出参数,可以这样定义:
        // var outputIdParam = new SqlParameter("@InsertedEmployeeId", SqlDbType.Int) { Direction = ParameterDirection.Output };
        // cmd.Parameters.Add(outputIdParam);

        try
        {
            dbConnection.Open();
            result = cmd.ExecuteNonQuery();
            // 如果需要获取输出参数的值:
            // var newEmployeeId = (int)outputIdParam.Value;
        }
        catch (SqlException ex)
        {
            // 这里可以注入ILogger来记录异常,比如:
            // _logger.LogError(ex, "执行存储过程Sp_Insert时发生错误");
            throw; // 根据业务需求选择抛出异常或返回错误标识
        }
        // using块会自动关闭连接并释放资源,无需手动调用Close()

        return result;
    }
}

3. 在控制器中使用

通过构造函数注入数据访问服务,在控制器方法里调用即可:

[ApiController]
[Route("api/employees")]
public class EmployeesController : ControllerBase
{
    private readonly IEmployeeRepository _employeeRepo;

    public EmployeesController(IEmployeeRepository employeeRepo)
    {
        _employeeRepo = employeeRepo;
    }

    [HttpPost]
    public IActionResult CreateEmployee([FromBody] Employee employee)
    {
        if (!ModelState.IsValid)
        {
            return BadRequest(ModelState);
        }

        var affectedRows = _employeeRepo.Insert(employee);
        return Ok(new { AffectedRows = affectedRows });
    }
}

关键注意事项

  • 连接生命周期:尽量在方法内部创建SqlConnection并使用using块包裹,ADO.NET的连接池会自动复用连接,避免长时间持有连接导致的资源浪费。
  • 参数安全:避免过度依赖AddWithValue,明确指定参数的SqlDbType和长度可以防止潜在的类型转换错误,同时提升数据库执行效率。
  • 依赖注入:通过接口和依赖注入来管理数据访问类,不仅能解耦业务逻辑和数据访问,还能方便后续的单元测试和服务替换。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 08:41:44