EF 4.1: Removing child object from collection does not delete it - why?
I have a some error : EF 4: Removing child object from collection does not delete it - why?
when i remove a child from the parent that the child is deleted when i call SaveChanges()
, it gives the follow error message:
The operation failed: The relationship could not be changed because one or more of the foreign-key properties is non-nullable. When a change is made to a relationship, the related foreign-key property is set to a null value. If the foreign-key do开发者_JAVA百科es not support null values, a new relationship must be defined, the foreign-key property must be assigned another non-null value, or the unrelated object must be deleted.
But with DbContext and EF 4.1, the "context.DeleteObject(recipe)" does not exist.
Any suggestion ?
[EDIT]
public void UpdateWithAttributes(Model model, IEnumerable<Entity> entities)
{
var modelOriginal = this.unitOfWork.Model.GetById(model.IModel);
this.unitOfWork.Context.Entry(modelOriginal).CurrentValues.SetValues(model);
UpdateEntityAttributeAssociations(modelOriginal, entities);
this.unitOfWork.Commit();
}
public void UpdateEntityAttributeAssociations(Model model, IEnumerable<Entity> current)
{
unitOfWork.Context.Entry(model).Collection(m => m.Entities).Load();
ICollection<Entity> original = model.Entities; // perhaps .ToList() necessary
// delete
if (original != null)
{
List<Entity> toDelete = GetToDelete(original, current);
foreach (Entity originalEntityToDelete in toDelete)
{
unitOfWork.Context.Entity.Remove(originalEntityToDelete);
}
}
// add, update
if (current != null)
{
foreach (Entity currentEntity in current)
{
// No need to set the UpdatedWhen. The trigger on the table will handle that.
if (original.Where(originalEntity => originalEntity.IEntity == currentEntity.IEntity).FirstOrDefault() == null)
{
model.Entities.Add(currentEntity);
}
}
}
}
You have to call:
context.Recipes.Remove(recipe);
Where Recipes
are DbSet<Recipe>
.
I guess that you are adding again what you have just deleted because removing from the DbSet
also removes internally the entity from the child collection original
. Then in the second loop you add the entity again. You could try to catch this situation like so:
public void UpdateEntityAttributeAssociations(Model model,
IEnumerable<Entity> current)
{
unitOfWork.Context.Entry(model).Collection(m => m.Entities).Load();
ICollection<Entity> original = model.Entities; // perhaps .ToList() necessary
// delete
List<Entity> toDelete = null;
if (original != null)
{
toDelete = GetToDelete(original, current);
foreach (Entity originalEntityToDelete in toDelete)
{
unitOfWork.Context.Entity.Remove(originalEntityToDelete);
}
}
// add, update
if (current != null)
{
foreach (Entity currentEntity in current)
{
if (toDelete == null || !toDelete.Contains(currentEntity))
{
if (original.Where(originalEntity => originalEntity.IEntity ==
currentEntity.IEntity).FirstOrDefault() == null)
{
model.Entity.Add(currentEntity);
}
}
}
}
}
I've also replaced your first line with explicit loading the child collection since your procedure to query the child entities manually looks unfamiliar to me, but I don't think that this is the problem (but I don't know).
Edit
I'm not sure if my code above helps to remove the exception you had. I don't know what happens if you add an entity to a collection which is already in Deleted
state and if this could throw this exception.
If the code doesn't help you could test if you also have the problem without the second (the Insert) loop. And how looks GetToDelete
exactly? And how look your Model
and Entity
class and their relationships? And is model.Entity
indeed another collection than model.Entities
(or is it a typo)?
精彩评论