I have run into an interesting problem with Entity Framework and based on the code I had to use to tackle it I suspect my solution is less than ideal. I have a 1-to-Many relationship between Table A and Table B where entities in TableB have a reference to TableA. I have a scenario where I want to simultaneously delete all children of a row in TableA and I thought this could be achieve by simply clearing the collection:
Entity.Children.Clear()
Unfortunately, when I attempted to save changes this produced as a Foreign Key violation.
A relationship is being added or deleted from an AssociationSet 'FK_EntityB_EntityA'. With cardinality constraints, a corresponding 'EntityB' must also be added or deleted.
The solution I came up with was to manually delete object via the entity context's DeleteObject(), but I just know this logic I am using has got to be wrong.
while (collection.Any()) Entities.DeleteObject(collection.First());
For one, the fact that I had to use a Where() loop seems far less than ideal, but I suppose that's purely a semantic assessment on my part. In any case, is there something wrong with how I am doing this, or is there perhaps a better way to clear a child entity collection of an entity such that Entity Framework properly calls a data store delete on all of the removed objects?
Clear()
removes the reference to the entity, not the entity itself.
If you intend this to be always the same operation, you could handle AssociationChanged
:
Entity.Children.AssociationChanged += new CollectionChangeEventHandler(EntityChildrenChanged); Entity.Children.Clear(); private void EntityChildrenChanged(object sender, CollectionChangeEventArgs e) { // Check for a related reference being removed. if (e.Action == CollectionChangeAction.Remove) { Context.DeleteObject(e.Element); } }
You can build this in to your entity using a partial class.
You can create Identifying relationship between parent and child entities and EF will delete child entity when you delete it from parent's collection.
public class Parent { public int ParentId {get;set;} public ICollection<Child> Children {get;set;} } public class Child { public int ChildId {get;set;} public int ParentId {get;set;} }
Mapping configuration:
modelBuilder.Entity<Child>().HasKey(x => new { x.ChildId, x.ParentId }); modelBuilder.Entity<Parent>().HasMany(x => x.Children).WithRequired().HasForeignKey(x => x.ParentId);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With