在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
相关产品推荐
相关产品推荐

