ASP.NET MVC DAL类调用单存储过程时@Action参数报错求助
问题解决:未提供@Action参数错误
核心错误点
1. GetEmployee方法的致命错误
- 未将
SqlCommand的CommandType设置为CommandType.StoredProcedure,默认会把User_CRUD当作普通SQL语句执行,无法识别存储过程参数。 @Action参数添加时机错误:在调用ExecuteReader()之后才添加参数,此时SQL命令已执行,参数完全无效。- 数据读取索引错误:employee表列顺序为
eno, ename, salary,代码错误将dr[0]映射为RollNo,与实际表结构不匹配。
2. 存储过程的潜在问题
存储过程中@ename和@salary参数未设置默认值,调用Getemp或Search时即使不需要这两个参数,也必须传入值,否则会触发参数缺失错误。
修复后的代码
1. 修改后的SQL存储过程
CREATE PROCEDURE User_CRUD @Action varchar(20), @eno int = NULL, @ename varchar(50) = NULL, @salary money = NULL AS IF @Action = 'Insert' BEGIN INSERT INTO employee (eno, ename, salary) VALUES (@eno, @ename, @salary) END ELSE IF @Action = 'Update' BEGIN UPDATE employee SET ename = @ename, salary = @salary WHERE eno = @eno END ELSE IF @Action = 'Delete' BEGIN DELETE FROM employee WHERE eno =@eno END ELSE IF @Action = 'Getemp' BEGIN SELECT * FROM employee END ELSE IF @Action = 'Search' BEGIN SELECT ename, salary FROM employee WHERE eno = @eno END
2. 修复后的DAL类方法
GetEmployee方法
public List<Models.Employee> GetEmployee() { List<Models.Employee> li = new List<Models.Employee>(); con.Open(); SqlCommand cmd = new SqlCommand("User_CRUD", con); // 必须设置为存储过程类型 cmd.CommandType = CommandType.StoredProcedure; // 执行前添加参数 cmd.Parameters.AddWithValue("@Action", "Getemp"); SqlDataReader dr = cmd.ExecuteReader(); if (dr.HasRows) { while(dr.Read()) { Models.Employee e1= new Models.Employee(); // 匹配employee表的列顺序:eno, ename, salary e1.Eno = int.Parse(dr["eno"].ToString()); e1.Ename = dr["ename"].ToString(); e1.Salary = double.Parse(dr["salary"].ToString()); // RollNo若不是表中列,请确认来源后调整,此处暂时注释 // e1.RollNo = ...; li.Add(e1); } } // 先关闭DataReader再关闭连接 dr.Close(); con.Close(); return li; }
SearchEmp方法(优化资源释放)
public Models.Employee SearchEmp(Models.Employee e1) { con.Open(); SqlCommand cmd = new SqlCommand("User_CRUD", con); cmd.CommandType= CommandType.StoredProcedure; cmd.Parameters.AddWithValue("@Action", "Search"); cmd.Parameters.AddWithValue("@eno", e1.Eno); SqlDataReader dr = cmd.ExecuteReader(); if (dr.HasRows) { if (dr.Read()) { e1.Ename= dr["ename"].ToString(); e1.Salary= double.Parse(dr["salary"].ToString()); } } // 先关闭DataReader再关闭连接 dr.Close(); con.Close(); return e1; }
额外优化建议
- 使用
using语句自动释放资源,避免连接泄漏:using(SqlCommand cmd = new SqlCommand("User_CRUD", con)) { cmd.CommandType = CommandType.StoredProcedure; cmd.Parameters.AddWithValue("@Action", "Getemp"); using(SqlDataReader dr = cmd.ExecuteReader()) { // 数据读取逻辑 } } - 避免使用
AddWithValue,推荐指定参数类型防止转换错误:cmd.Parameters.Add(new SqlParameter("@Action", SqlDbType.VarChar, 20) { Value = "Getemp" });
内容的提问来源于stack exchange,提问作者Nani
相关产品推荐
相关产品推荐

