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

本文关键字:数据库 MVC 冲突 语句 FOREIGN KEY 约束 UPDATE | 更新日期: 2023-09-27 18:08:52

我得到了两个表,一个是UserCommentUserComment都将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)

我做错了什么?我只是想更新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>

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

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