UPDATE语句与FOREIGN KEY约束冲突.MVC(数据库先行)
本文关键字:数据库 MVC 冲突 语句 FOREIGN KEY 约束 UPDATE | 更新日期: 2023-09-27 18:08:52
我得到了两个表,一个是User
和Comment
。User
和Comment
都将Id
作为主键。Comment
也有一个User
Id的FK键,称为CreatorUserID
。一旦我尝试编辑Comment
行,我得到以下错误:
UPDATE语句与FOREIGN KEY约束冲突"FK_Comment_User"。冲突发生在数据库"XX"表中"dbo。用户",列'Id'.
我没有在Comment
表中触摸FK CreatorUserId
。我还确保在SQL Server中为fk关系启用级联更新和删除。
我的编辑动作是这样的:
public ActionResult Edit(Guid? id) {
Comment comment = db.Comment.Find(id);
if (review == null) {
return HttpNotFound();
}
return View(comment);
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit([Bind(Include = "Id,CreatorUserID,Description,Title")] Comment comment) {
if (ModelState.IsValid) {
db.Entry(comment).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
return View(comment);
}
额外的信息:
数据库先行
使用Id的Guids
这是如何url看起来像之前我点击更新结果错误:http://localhost:41003/Comment/Edit/8cab7ab2-3184-e611-9d7a-6c71d98d2a40
用户表
Id(Guid) PK
Email(nvarchar)
Password(nvarchar)
Comment-table
Id(Guid) PK
CreatorUserID(Guid) FK
Description(nvarchar) // this and title is the only thing I'm trying to edit
Title(nvarchar)
我做错了什么?我只是想更新Description
和Title
。我没有触摸Id
或CreatorUserID
更新期间。
视图:(我只包含我正在编辑的属性的表单控件)
<div class="form-group">
@Html.LabelFor(model => model.Title, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Title, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Title, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.Description, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Description, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Description, "", new { @class = "text-danger" })
</div>
</div>
异常的原因是您没有为属性CreatorUserID
生成表单控件,所以当您提交时,DefaultModelBinder
初始化Comment
的实例从路由值设置Id
的值,从表单值设置Title
和Description
的值。但是CreatorUserID
仍然是Guid
的默认值,所以当你更新数据库时,它正在寻找一个不存在的Id = {00000000-0000-0000-0000-000000000000}
的User
。
您可以通过在CreatorUserID
的视图中添加一个隐藏输入来解决这个问题,以便将其值发布并绑定到模型
@Html.HiddenFor(m => m.CreatorUserID)
然而,一个更好的解决方案,将解决其他问题,以及使用视图模型(参考什么是MVC中的ViewModel ?)。
public class CommentVM
{
public Guid? ID { get; set; }
public string Title { get; set; }
public string Description { get; set; }
}
并根据需要用view指定显示和验证属性来修饰属性。然后需要更改视图以使用视图模型而不是数据模型
@model yourAssembly.CommentVM
和控制器方法变成
public ActionResult Edit(Guid id) { // should not be nullable
Comment comment = db.Comment.Find(id);
if (comment == null) {
return HttpNotFound();
}
// Initialize a view model
CommentVM model = new CommentVM()
{
ID = id,
Title = comment.Title,
Description = comment.Description
};
return View(model); // return view model
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(CommentVM model) { // BindAttribute not required
if (!ModelState.IsValid) {
return View(model);
}
// Get the data model
Comment comment = db.Comment.Where(x => x.Id == model.ID).FirstOrDefault();
// Update its properties
comment.Title = model.Title;
comment.Description = model.Description;
// Save and redirect
db.SaveChanges();
return RedirectToAction("Index");
}
请注意,您不需要为ID
属性隐藏输入,因为它将从url的路由值绑定(只要该属性命名为ID
并且您使用默认路由- url: "{controller}/{action}/{id}
)