86458

Error “A referential integrity constraint violation occurred”

Question:

Can you please help me with my code?

I have 2 models:

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 }

And trying to make an Edit function. Controller code:

// 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); }

And my View:

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

And when i try just to click Save button (even if i dont do any changes) an error occured: A referential integrity constraint violation occurred: The property value(s) of 'Author.Id' on one end of a relationship do not match the property value(s) of 'Book.AuthorId' on the other end. Error is in dbBooks.Entry(book).State = EntityState.Modified;

If I try to add book.Author = null; it is logically than my AuthorNames` start to disappear...

Also I was trying to put something in Html.HiddenFor, but maybe I was doing something wrong, but nothing changed.

Answer1:

Well, you couldn't modify AuthorName in Book's editor view. You need another view for Author to modify it.

book.Author - cannot be null, becouse its navigation property and can only be like readonly mode. So just remove editormodel for author.authorname

Modified books list:

Book bookEdit = dbBooks.Books.ToList().Where(a => a.Id == id).SingleOrDefault();

Answer2:

Look what you need to do, i got it now. You just need selectList of all Author's and in a view name will be auto selected on AuthorId book's field. Make new one form-group with

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

And in Your Edit action:

// 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); }

Answer3:

Again many thanks!

But using DropDownList dont allow me to edit Author`s name.. But that solution is rly good.

I need to edit all 4 fields like name, title, year and price.

I try to make something like composite model:

public class BookAuthorCompositeModel { public Author author { get; set; } public Book book { get; set; } }

Change my get method:

// 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); }

and it displays all I need (i tap "edit" and see information about name, title, year and price).

My view is:

@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") }

but something wrong is in Post method:

[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(); leads to error.. I think using this kind of ViewModel helps to edit all rows, but it doesnt sade data to DB...

Maybe you could help with this please?

Recommend

  • DDL fails to change during AJAX call MVC
  • Binding a dictionary containing a list in MVC4
  • ASP.NET MVC4 Model's Child Collection Drop Down List not binding properly
  • .NET MVC3 Html.HiddenFor inside of foreach loop expecting a collection?
  • .NET datepicker format gives “MM-dd-yyyy” instead of “MM/dd/yyyy”
  • why toast message not showing in marshmallow 6.0.1 while showing it lower than 6.0
  • Rendering a partial View with Ajax Unobtrusive
  • Auto regex - fix needed
  • Rails / Bootstrap / HAML - How to convert this code to display flash messages to HAML?
  • Automatically Replace Misspellings with Suggestions for long lists of terms
  • New BFC “clearing” floating boxes
  • Vertical align button in the middle of the column- bootstrap
  • Creating a EditorTemplate MVC3
  • Howto take a glimpse into mscorlib?
  • Jquery valildator not working
  • How to use compare validator to compare the data between two dropdownlists values?
  • doPostBack from C# with JavaScript
  • How can I have equal heights for inner elements of flexbox grid/boxes/cards without using jQuery?
  • Multibinding Multiselection ListView
  • passing a javascript variable to PHP with xmlhttprequest
  • Creating a Multi-Step Modal Using Jquery
  • my tic-tac-toe program in matlab does not work [closed]
  • Lock Horizontal View
  • OpenGL ES texture problem, 4 duplicate columns and horizontal lines (Android)
  • MySQL WHERE-condition in procedure ignored
  • Web-crawler for facebook in python
  • How to get icons for entities from eclipse?
  • trying to dynamically update Highchart column chart but series undefined
  • Proper way to use connect-multiparty with express.js?
  • Load html files in TinyMce
  • How to stop GridView from loading again when I press back button?
  • Bitwise OR returns boolean when one of operands is nil
  • sending mail using smtp is too slow
  • MATLAB: Piecewise function in curve fitting toolbox using fittype
  • JaxB to read class hierarchy
  • Busy indicator not showing up in wpf window [duplicate]
  • Why is Django giving me: 'first_name' is an invalid keyword argument for this function?
  • Binding checkboxes to object values in AngularJs
  • How can I use `wmic` in a Windows PE script?
  • java string with new operator and a literal