locked
Self-tracking entities - Delete problem RRS feed

  • Question

  • Hi,

    The normal pattern I use when deleting by ID is this:

    new Repository().DeleteByID(id);
    
    class Repository{
    
    Repository(){
      this.Context = new Context();
    }
    
    GetByID(id){
      return (from x in this.Context.Entities 
           where x.ID == id select x).FirstOrDefault();
    }
    
    DeleteByID(id){
      Entity e = new Repository().GetByID(id);
      Delete(e);
    }
    
    Delete(Entity e){
      e.MarkAsDeleted();
      this.Context.Entities.ApplyChanges(e);
      this.Context.SaveChanges();
      e.AcceptChanges();
    }
    

    I fetch the entity with a fresh context to be able to ApplyChanges as I normally work with self-tracking entities (as described by the answer in this thread: http://social.msdn.microsoft.com/Forums/en-US/adonetefx/thread/a8f52561-45cd-429d-97f2-872d3490f190). I know that I could just working "attached" and delete the object from the context in this case, but this would not match with how we normally delete objects (see Delete method).

    This works perfectly, but I have now found myself in a more complicated situation that I will not try to simplify and explain.

    In this situation, I would like to fetch the object that is to be deleted and also fetch related entities before deletion.

    If I change the DeleteByID-method to this ...

    DeleteByID(id){
      Entity e = new Repository().GetByID(id);
      e.RelatedEntity = new RelatedEntityRepository().GetByID(e.RelatedEntityID);
      Delete(e);
    }
    
    
    
    Delete(Entity e){
      e.MarkAsDeleted();
      e.RelatedEntity.MarkAsDeleted();
      this.Context.Entities.ApplyChanges(e);
      this.Context.SaveChanges();
      e.AcceptChanges();
      e.RelatedEntity.AcceptChanges();
    }
    

    ... something goes wrong and I get a foreign key exception, probably because the related entities are not deleted properly, but why???

    The code works fine if I do not fetch things by using two querys but instead fetch the entity and its related object in the same query (which I do not want to do in this situation) like this ...

    GetByID(id){
     return (from x in this.Context.Entities
      .Include("RelatedEntity")
      where x.ID == id select x).FirstOrDefault();
    }
    
    ... which boggles me completely.


    Can someone shed any light on this situation?

     

    • Edited by JH1984 Thursday, August 12, 2010 8:35 AM typo
    Thursday, August 12, 2010 8:30 AM

Answers

  • That's what I thought as well. Is it possible to see the "state" of the relationship? I know that you can monitor entity.changetracker.State, but this state was unmodified for both entities taking part in the relationship.

    To call acceptchanges on both entities did unfortunately not work.

    I have now managed to solve this problem though. What I needed to do was to use the same context for both select querys and to also turn of change tracking when "connecting" the entities. After doing this, I could mark all the entities as deleted as usual and applychanges before saving.

    Thanks for the answer though :)

    • Marked as answer by JH1984 Friday, August 20, 2010 11:50 AM
    Friday, August 20, 2010 11:50 AM

All replies

  • In the more complicated approach where you are deleting an entity and its related entity, this line:

     e.RelatedEntity = new RelatedEntityRepository().GetByID(e.RelatedEntityID);

    Actually makes the relationship between e and e.RelatedEntity "Added". Which is a bit different when you just query for the relationship and there are no Added relationships on the entities. One suggestion would be to call AcceptChanges on both entities after you query for them and set the relationship. If that doesn't work, check to see if there is any other difference in the overall state of the entities between your two patterns.

    Jeff


    This posting is provided "AS IS" with no warranties, and confers no rights.
    Wednesday, August 18, 2010 2:36 PM
  • That's what I thought as well. Is it possible to see the "state" of the relationship? I know that you can monitor entity.changetracker.State, but this state was unmodified for both entities taking part in the relationship.

    To call acceptchanges on both entities did unfortunately not work.

    I have now managed to solve this problem though. What I needed to do was to use the same context for both select querys and to also turn of change tracking when "connecting" the entities. After doing this, I could mark all the entities as deleted as usual and applychanges before saving.

    Thanks for the answer though :)

    • Marked as answer by JH1984 Friday, August 20, 2010 11:50 AM
    Friday, August 20, 2010 11:50 AM