Reputation: 2079
I am working on Database first approach with Entity Framework 4.1. I have 2 many to many related entities Book and Library. I also have one junction table with 10 columns to store information about the particular copy of the book in Library with one to many relation with both BOOK and LIBRARY entities. I have created a view which submits a JSON object with child object in it which matches the definition of my BookVieMOdel. The view is working just fine but I am having trouble adding new entries to the junction table in the controller. I am getting error saying "Adding a relationship with an entity which is in the Deleted state is not allowed".
I guess the error is referring to the deleted object which were deleted when by the book.LibraryBookCopies.Clear();
but can't think of doing it other way.
Thanks,
CONTROLLER:
[HttpPost]
public ActionResult Edit(BookViewModel bookv)
{
Mapper.CreateMap< BookViewModel,Book>();
Book book = Mapper.Map<BookViewModel,Book>(bookv);
db.Books.Attach(book);
db.ObjectStateManager.ChangeObjectState(book, EntityState.Modified);
//Add library ref to each libraryBookCopies object in Book
foreach (LibraryBookCopy lBC in book.LibraryBookCopies)
{
lBC.Library = db.Libraries.Single(l => l.LibraryId == lBC.LibraryId);
}
//Remove all currently related records
book.LibraryBookCopies.Clear();
//Add copies from ViewModel to book object
foreach (LibraryBookCopy lBC in bookv.LibraryBookCopies)
{ book.LibraryBookCopies.Add(lBC); //Error here }
db.SaveChanges();
return RedirectToAction("Index");
}
Upvotes: 0
Views: 4206
Reputation: 2079
[HttpPost]
public ActionResult Edit(BookViewModel bookv)
{
//create maps
Mapper.CreateMap<LibraryBookCopyViewModel, LibraryBookCopy>();
Mapper.CreateMap<BookViewModel, Book>();
//convert view objects to model objects
Book book = Mapper.Map<BookViewModel, Book>(bookv);
List<LibraryBookCopy> bookCopiesFromView = Mapper.Map<List<LibraryBookCopyViewModel>, List<LibraryBookCopy>>(bookv.LibraryBookCopies);
List<LibraryBookCopy> toBeDeletedLibraryBookCopies = new List<LibraryBookCopy>();
//this has to be executed before db.Books.Attach
book.LibraryBookCopies.Clear();
//Add or update book copies
foreach (LibraryBookCopy bc in bookCopiesFromView)
{
if (bc.LibraryBookCopyId != 0)
{
db.LibraryBookCopies.Attach(bc);
db.ObjectStateManager.ChangeObjectState(bc, EntityState.Modified);
}
else
{
db.LibraryBookCopies.Attach(bc);
db.ObjectStateManager.ChangeObjectState(bc, EntityState.Added);
}
}
db.Books.Attach(book);
if (bookCopiesFromView.Count == 0) //if all the copies are delted from view, delete all from
{
db.LibraryBookCopies.Where(c => c.BookId == book.BookId).ToList().ForEach(l => db.LibraryBookCopies.DeleteObject(l));
}
else
{
toBeDeletedLibraryBookCopies = book.LibraryBookCopies.Except(bookCopiesFromView).ToList();
foreach (LibraryBookCopy bc in toBeDeletedLibraryBookCopies)
{
db.ObjectStateManager.ChangeObjectState(bc, EntityState.Deleted);
}
}
db.ObjectStateManager.ChangeObjectState(book, EntityState.Modified);
db.SaveChanges();
return RedirectToAction("Index");
}
Upvotes: 0
Reputation: 382
You've said the error is "entity which is in the Deleted state is not allowed" I'm wondering if are having problems with WillCascadeOnDelete and that the Book is being deleted. See, http://weblogs.asp.net/manavi/archive/2011/01/23/associations-in-ef-code-first-ctp5-part-3-one-to-one-foreign-key-associations.aspx
Upvotes: 2
Reputation: 695
Maybe try saving the changes before adding new records?
//Remove all currently related records
book.LibraryBookCopies.Clear();
db.SaveChanges();
//Add copies from ViewModel to book object
foreach (LibraryBookCopy lBC in bookv.LibraryBookCopies)
{ book.LibraryBookCopies.Add(lBC); //Error here }
Upvotes: 0