我有两张桌子,一张User
和Comment
。 User
和Comment
都将Id
作为主键。 Comment
也有User
ID的FK密钥,即CreatorUserID
。尝试编辑Comment
行后,出现以下错误:
UPDATE语句与FOREIGN KEY约束冲突 " FK_Comment_User&#34 ;.冲突发生在数据库" XX",表中 " dbo.User",专栏' Id'。
我没有触及CreatorUserId
表格中的FK Comment
。我还确保在SQL Server中为FK关系更新和删除启用Cascade。
这就是我的编辑操作的样子:
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)
评论表
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>
答案 0 :(得分:1)
异常的原因是您没有为属性CreatorUserID
生成表单控件,所以当您提交时,DefaultModelBinder
初始化和Comment
的实例设置Id
的值1}}来自路由值以及来自表单值的Title
和Description
的值。但CreatorUserID
仍然是Guid
的默认设置,因此当您更新数据库时,它正在寻找User
Id = {00000000-0000-0000-0000-000000000000}
,而CreatorUserID
不存在。
您可以通过在@Html.HiddenFor(m => m.CreatorUserID)
的视图中添加隐藏输入来解决此问题,以便将其值发布并绑定到模型
public class CommentVM
{
public Guid? ID { get; set; }
public string Title { get; set; }
public string Description { get; set; }
}
然而,解决其他问题的更好的解决方案是使用视图模型(参考What is ViewModel in MVC?)。
@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
请注意,您不需要ID
属性的隐藏输入,因为它将从网址的路由值绑定(只要该属性名为url: "{controller}/{action}/{id}
并且您使用默认路线 - 1@|@2@|@3
)