UPDATE语句与FOREIGN KEY约束冲突.. MVC(数据库优先)

时间:2016-09-27 01:12:28

标签: c# sql-server asp.net-mvc entity-framework

我有两张桌子,一张UserCommentUserComment都将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)

我做错了什么?我只想更新DescriptionTitle。在更新期间,我无法触摸IdCreatorUserID

查看:(我只包含了我正在编辑的属性的表单控件)

<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>

1 个答案:

答案 0 :(得分:1)

异常的原因是您没有为属性CreatorUserID生成表单控件,所以当您提交时,DefaultModelBinder初始化和Comment的实例设置Id的值1}}来自路由值以及来自表单值的TitleDescription的值。但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