I have created a model POCO class called Recipe
; a corresponding RecipeRepository
persists these objects. I am using Code First on top of an existing database.
Every Recipe
contains an ICollection<RecipeCategory>
of categories that link the Recipes
and the Categories
table in a many-to-many relationship. RecipeCategory
contains the corresponding two foreign keys.
A simplified version of my controller and repository logic looks like this (I have commented out all checks for authorization, null
objects etc. for simplicity):
public ActionResult Delete(int id)
{
_recipeRepository.Remove(id);
return View("Deleted");
}
The repository's Remove
method does nothing but the following:
public void开发者_开发百科 Remove(int id)
{
Recipe recipe = _context.Recipes.Find(id);
_context.Recipes.Remove(recipe);
_context.SaveChanges();
}
Howevery, the code above does not work since I receive a System.InvalidOperationException
every time I run it: Adding a relationship with an entity which is in the Deleted state is not allowed.
What does the error message stand for and how can I solve the problem? The only thing I try to achieve is deleting an entity.
@Ladislav: I have replaced ICollection<RecipeCategory>
by ICollection<Category>
. Accidentially, ReSharper refactored away the virtual
keyword.
However, the problem remains — I cannot delete a Category
from a Recipe
entity. The following code does not persist the deletion of the categories to the database:
private void RemoveAllCategoriesAssignedToRecipe()
{
foreach (Category category in _recipe.Categories.ToArray())
{
_recipe.Categories.Remove(category);
category.Recipes.Remove(_recipe);
}
_context.SaveChanges();
}
I have debugged the code and can confirm that the collections are modified correctly — that is, they contain no elements after the loop (I have also used the Clear()
method). After calling SaveChanges()
, they are populated again.
What am I doing wrong?
(Maybe it is important: I am using the Singleton pattern to only have one instance of the context.)
I was able to solve the problem the following way:
private void RemoveAllCategoriesAssignedToRecipe()
{
foreach (Category category in _recipe.Categories.ToArray())
{
Category categoryEntity = _categoryRepository.Retrieve(category.CategoryID);
var recipesAssignedToCategory = categoryEntity.Recipes.ToArray();
categoryEntity.Recipes.Clear();
foreach (Recipe assignedRecipe in recipesAssignedToCategory)
{
if (assignedRecipe.RecipeID == _recipe.RecipeID)
{
continue;
}
categoryEntity.Recipes.Add(assignedRecipe);
}
_context.Entry(categoryEntity).State = EntityState.Modified;
}
_recipe.Categories.Clear();
_context.SaveChanges();
}
精彩评论