Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Entity Framework - Clear a Child Collection

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?

like image 499
Nathan Taylor Avatar asked Jan 13 '10 17:01

Nathan Taylor


2 Answers

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.

like image 174
Craig Stuntz Avatar answered Sep 20 '22 01:09

Craig Stuntz


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); 
like image 32
syned Avatar answered Sep 23 '22 01:09

syned