Undo delete entity

5 posts, 0 answers
  1. Erik
    Erik avatar
    36 posts
    Member since:
    Jun 2012

    Posted 07 Oct 2012 Link to this post

    Is it possible to 'undo' a dbContext.Delete operation?
  2. TSE
    TSE avatar
    381 posts
    Member since:
    Sep 2008

    Posted 09 Oct 2012 Link to this post

    Hi Erik,

    I believe there are two ways of doing this, but as always it depends... on how complex the entity you deleted is.

    1)
    You could do a rollback, but it is rather coarse-grained, meaning.. you rollback any changes applied to the context.

    2)
    You could Add the entity to the Context again.

    Regards

    Henrik
  3. DevCraft banner
  4. Doroteya
    Admin
    Doroteya avatar
    502 posts

    Posted 11 Oct 2012 Link to this post

    Hello,

    Henrik, thank you for the response. I just want to explain that while you are right about the first way, while the second one is possible only if a few conditions are fulfilled.

    Rollback Changes
    In OpenAccess, dbContext.Delete(...) marks the object for removal and to undo it before the transaction (to roll it back) you can use dbContext.ClearChanges() (more about this method you can read here). Note that, it will cancel all pending changes from the context (including dbContext.Delete(..)) and if you intend to use it, be very careful with context management.

    Adding back an object
    In OpenAccess, the lifecycle of the objects you make persistent by calling dbContext.Add(...) is as follows: transient -> persistent new -> persistent new deleted or hollow. That means that when you create an object in your code, add it to the context, mark it for removal and than add it again, the second dbContext.Add(...) command will be ignored. In other words you cannot do
        dbContext.Add(someObject);
        dbContext.Delete(someObject);
        dbContext.Add(someObject);
    in the same transaction.

    The other scenario when you retrieve an existing object from the database, mark it for removal and then add a new object with the same property values, is possible and it looks roughly like this (using the SofiaCarRental database):
    using (EntityDiagrams dbContext = new EntityDiagrams())
                {
                    //Retrieve an object from the database
                    string carTagNumber = "TE 9876 IK";
                    Car carToDelete = dbContext.Cars.FirstOrDefault(c => c.TagNumber == carTagNumber);
     
                    //Add some code to preserve the values
                    //of the properties of carToDelete
                    string carModel = carToDelete.Model;
     
                    //carToDelete is marked for delete and the values
                    //of all its properties are set to NULL
                    dbContext.Delete(carToDelete);
     
                    //An object with properties equal to the properties
                    //of carToDelete is created
                    Car carToAdd = new Car
                    {
                        TagNumber = carTagNumber,
                        Model = carModel
                        //Add values for the rest of the properties of carToAdd
                    };
     
                    //Add carToAdd in the context
                    dbContext.Add(carToAdd);
     
                    //Once you save the changes the delete statement will be executed
                    //and after that the new object will be added to the database with
                    //the same property values.
                    dbContext.SaveChanges();
                }

    For additional information about the lifecycle of the objects in OpenAccess, I suggest you to check here and here.

    If you have any other questions or you are trying to implement another scenario, do not hesitate to get back to us.


    All the best,
    Doroteya
    the Telerik team
    Follow @OpenAccessORM Twitter channel to be the first one to get the latest updates on new releases, tips and tricks and sneak peeks at our product labs!
  5. TSE
    TSE avatar
    381 posts
    Member since:
    Sep 2008

    Posted 11 Oct 2012 Link to this post

    Hi Doroteya,

    Thanks for the clarification.

    That was exactly what I meant by the phrase: "it depends... on how complex the entity you deleted is" :-)

    Because you are actually creating a brand new instance and just copy the properties of the deleted object.

    So if your object graph is deep or have many properties per level, this is quite cumbersome - at least doing it manually (copy property by property - referened object by object)

    Clone to rescue

    /Henrik
  6. Erik
    Erik avatar
    36 posts
    Member since:
    Jun 2012

    Posted 11 Oct 2012 Link to this post

    Thanks Henrik & Doroteya for your replies. I decided to add the items I want to delete to a separate list, and only mark them for deletion just before calling dbContext.SaveChanges.
Back to Top
DevCraft banner