Bishnu Paudel
Bishnu Paudel

Reputation: 2079

Save/Update error for entities with many to many relation

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

Answers (3)

Bishnu Paudel
Bishnu Paudel

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

melutovich
melutovich

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

Vasile Laur
Vasile Laur

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

Related Questions