ASP.NET MVC中用ADO.NET显示数据库生成的Dno并提交数据
解决方案
你的核心问题是Dno是数据库插入后才会生成的计算列,无法在提交前获取到真实有效且唯一的值,所以需要调整流程:先提交部门名称生成记录,再把数据库返回的Dno展示到页面上。以下是具体代码修改步骤:
1. 修改存储过程spAddDepartments
让存储过程在插入数据后,返回自动生成的id和Dno:
CREATE PROCEDURE spAddDepartments @Dname VARCHAR(50), @NewId INT OUTPUT, @NewDno VARCHAR(50) OUTPUT AS BEGIN SET NOCOUNT ON; INSERT INTO Department(Dname) VALUES(@Dname); -- 获取当前会话生成的identity值 SET @NewId = SCOPE_IDENTITY(); -- 生成对应Dno(和表计算逻辑一致) SET @NewDno = CONCAT('Dno_', @NewId); END
2. 重构仓储层AddDepartment方法
修改方法逻辑,获取存储过程返回的输出参数,返回包含完整信息的Department对象:
public Department AddDepartment(Department obj) { connection(); SqlCommand cmd = new SqlCommand("spAddDepartments", con); cmd.CommandType = CommandType.StoredProcedure; // 传入部门名称参数 cmd.Parameters.AddWithValue("@Dname", obj.Dname); // 定义输出参数:新生成的id SqlParameter outIdParam = new SqlParameter("@NewId", SqlDbType.Int) { Direction = ParameterDirection.Output }; cmd.Parameters.Add(outIdParam); // 定义输出参数:新生成的Dno SqlParameter outDnoParam = new SqlParameter("@NewDno", SqlDbType.VarChar, 50) { Direction = ParameterDirection.Output }; cmd.Parameters.Add(outDnoParam); con.Open(); cmd.ExecuteNonQuery(); con.Close(); // 组装并返回包含Dno的部门对象 return new Department { id = Convert.ToInt32(outIdParam.Value), Dno = outDnoParam.Value.ToString(), Dname = obj.Dname }; }
3. 调整控制器逻辑
GET方法(打开添加页面)
默认返回空模型,Dno文本框留空(因为还未生成):
[HttpGet] public ActionResult AddDepartment() { return View(new Department()); }
POST方法(提交数据)
接收仓储返回的完整部门对象,传递给视图展示Dno:
[HttpPost] public ActionResult AddDepartment(Department Dep) { try { if (ModelState.IsValid) { DepartmentRep repo = new DepartmentRep(); Department createdDept = repo.AddDepartment(Dep); ModelState.Clear(); ViewBag.Message = "Details added successfully"; // 将包含Dno的对象传给视图,用于显示 return View(createdDept); } return View(Dep); } catch { ViewBag.Error = "Failed to add department"; return View(Dep); } }
4. 修改视图AddDepartment.cshtml
将Dno文本框设置为只读,确保用户无法编辑,同时在提交成功后显示生成的值:
@model YourNamespace.Models.Department @{ ViewBag.Title = "Add Department"; } <h2>Add Department</h2> @if (!string.IsNullOrEmpty(ViewBag.Message)) { <div class="alert alert-success">@ViewBag.Message</div> } @if (!string.IsNullOrEmpty(ViewBag.Error)) { <div class="alert alert-danger">@ViewBag.Error</div> } @using (Html.BeginForm()) { @Html.AntiForgeryToken() <div class="form-horizontal"> <hr /> <div class="form-group"> @Html.LabelFor(model => model.Dno, new { @class = "control-label col-md-2" }) <div class="col-md-10"> <!-- 设置只读,禁止用户修改 --> @Html.TextBoxFor(model => model.Dno, new { @class = "form-control", @readonly = "readonly" }) </div> </div> <div class="form-group"> @Html.LabelFor(model => model.Dname, new { @class = "control-label col-md-2" }) <div class="col-md-10"> @Html.EditorFor(model => model.Dname, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.Dname, "", new { @class = "text-danger" }) </div> </div> <div class="form-group"> <div class="col-md-offset-2 col-md-10"> <input type="submit" value="Create" class="btn btn-default" /> </div> </div> </div> } <div> @Html.ActionLink("Back to List", "Index") </div>
补充说明
如果一定要在提交前显示一个“预测”的Dno(存在数据一致性风险,不推荐),可以在GET方法中预先计算下一个可能的id:
[HttpGet] public ActionResult AddDepartment() { DepartmentRep repo = new DepartmentRep(); var depts = repo.GetDepartmentList(); // 计算下一个可能的id(如果表为空则默认1) int nextId = depts.Any() ? depts.Max(d => d.id) + 1 : 1; return View(new Department { Dno = $"Dno_{nextId}" }); }
⚠️ 注意:这种方式生成的Dno可能和实际插入后的不一致(比如其他用户同时插入数据、数据库identity有间隙等),仅用于展示参考,不能作为业务依据。
内容的提问来源于stack exchange,提问作者Divya
相关产品推荐
相关产品推荐

