错误“发生了参照完整性约束违规”
您能否帮我解决我的代码问题?错误“发生了参照完整性约束违规”
我有2种型号:
public class Author
{
public int Id { get; set; }
public string AuthorName { get; set; }
public IEnumerable<Book> Books { get; set; }
}
public class Book
{
public int Id { get; set; }
public string Title { get; set; }
public int YearPublish { get; set; }
public int Price { get; set; }
public int? AuthorId { get; set; } //FK
public Author Author { get; set; } //navigation property
}
,并试图进行编辑的功能。 控制器代码:
// GET: Books/Edit/5
public ActionResult Edit(int? id)
{
if (id == null)
{
return HttpNotFound();
}
Book bookEdit = dbBooks.Books.Include(a => a.Author).Where(a => a.AuthorId == id).Single();
return View(bookEdit);
}
// POST: Books/Edit/5
[HttpPost]
public ActionResult Edit(Book book)
{
if (ModelState.IsValid)
{
// TODO: Add update logic here
//book.Author = null; //AuthorName cant be edited
dbBooks.Entry(book).State = EntityState.Modified;
dbBooks.SaveChanges();
return RedirectToAction("Index");
}
return View(book);
}
而我的观点:
<div class="form-horizontal">
<h4>Book</h4>
<hr />
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
@Html.HiddenFor(model => model.Id)
<div class="form-group">
@Html.LabelFor(model => model.Author.AuthorName, "AuthorName", htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Author.AuthorName, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Author.AuthorName, "", new { @class = "text-danger" })
</div>
</div>
<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.YearPublish, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.YearPublish, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.YearPublish, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.Price, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Price, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Price, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Save" class="btn btn-default" />
</div>
</div>
</div>
,当我尝试只是为了点击保存按钮(即使我没有做任何修改)发生错误: 参照完整性约束冲突发生:关系一端的'Author.Id'的属性值与另一端的'Book.AuthorId'的属性值不匹配。 错误在dbBooks.Entry(book).State = EntityState.Modified;
如果我尝试添加book.Author = null;
它在逻辑上是比我AuthorNames`开始消失......
此外,我试图把在Html.HiddenFor东西,但也许我做错了什么,但什么都没有改变。
那么,你无法修改Book的编辑器视图中的AuthorName。您需要其他视图供作者修改它。
book.Author
- 不能是null
,因为它的导航属性,只能像readonly模式。因此,只要删除editormodel为author.authorname
修改书单:
Book bookEdit = dbBooks.Books.ToList().Where(a => a.Id == id).SingleOrDefault();
谢谢!但仍不明白如何实现作者姓名(来自模型作者)和书籍模型的标题,年份等editin ... – di0nise4ka
看看你需要做什么,我得到了现在。您只需要所有作者的选择列表,并且在视图名称中将自动选择AuthorId书籍的字段。 结交新一种形式,组
<div class="form-group">
@Html.LabelFor(model => model.AuthorId, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@(Html.DropDownListFor(p => p.AuthorId, (SelectList)ViewBag.Authors, new { @class = "form-control" }))
@Html.ValidationMessageFor(model => model.AuthorId, "", new { @class = "text-danger" })
</div>
</div>
,并在您编辑动作:
// GET: Books/Edit/5
public ActionResult Edit(int? id)
{
if (id == null)
{
return HttpNotFound();
}
Book bookEdit = dbBooks.Books.Where(a => a.Id == id).Single();
// UPDATED
var list = dbBooks.Books.Select(x => new { ID = x.Id, AuthorName = x.AuthorName });
ViewBag.Authors = new SelectList(list, "Id", "AuthorName");
// UPDATED
return View(bookEdit);
}
再次非常感谢!
但是使用DropDownList不允许我编辑作者的名字..但是这个解决方案非常好。
我需要编辑所有4个字段,如名称,标题,年份和价格。
我尽量让类似的复合模式:
public class BookAuthorCompositeModel
{
public Author author { get; set; }
public Book book { get; set; }
}
更改我的get方法:
// GET: Books/Edit/5
public ActionResult Edit(int? id)
{
if (id == null)
{
return HttpNotFound();
}
var compModel = new BookAuthorCompositeModel();
compModel.book = dbBooks.Books.ToList().Where(a => a.Id == id).SingleOrDefault();
compModel.author = dbBooks.Authors.ToList().Where(x => x.Id == id).SingleOrDefault();
return View(bookEdit);
}
,它会显示所有我需要(我点击“编辑”,并看到有关名称的信息,标题,年份和价格)。
我的看法是:
@model BookStorage.Models.BookAuthorCompositeModel
@{
ViewBag.Title = "Edit";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Edit</h2>
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Book</h4>
<hr />
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
@Html.HiddenFor(model => model.book.Id)
<div class="form-group">
@Html.LabelFor(model => model.author.AuthorName, "AuthorName", htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.author.AuthorName, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.author.AuthorName, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.book.Title, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.book.Title, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.book.Title, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.book.YearPublish, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.book.YearPublish, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.book.YearPublish, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.book.Price, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.book.Price, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.book.Price, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Save" class="btn btn-default" />
</div>
</div>
</div>
}
<div>
@Html.ActionLink("Back to List", "Index")
</div>
@section Scripts {
@Scripts.Render("~/bundles/jqueryval")
}
但蹊跷的是Post方法:
[HttpPost]
public ActionResult Edit(Book book)
{
if (ModelState.IsValid)
{
dbBooks.Entry(BAmodel.book).State = EntityState.Modified;
dbBooks.Entry(BAmodel.author).State = EntityState.Modified;
dbBooks.SaveChanges();
return RedirectToAction("Index");
}
return View(book);
}
dbBooks.SaveChanges();导致错误..我认为使用这种ViewModel有助于编辑所有行,但它不会将数据拖到DB ...
也许你可以帮助这个请吗?
这可能不是问题,但我认为在您的编辑动作中,您应该查询Book的'Id',而不是'AuthorId':'Book bookEdit = dbBooks.Books.Include(a => a.Author)。 Where(a => a.Id == id).Single();' – Marc