Is there way to attach only the entity without other attached objects?

6 posts, 0 answers
  1. Silvio Silva Junior
    Silvio Silva Junior avatar
    100 posts
    Member since:
    Mar 2010

    Posted 28 Nov 2013 Link to this post

    Hello.

    I have been reading the open access orm documentation and I saw this information:

    • If the object being attached has related objects, those objects are also attached to the context.
    I have tested, and the changes of the attached objects to my "main" object are saved in database too.

    Is there a way to deatach all objects from my main object?

    Regards.
  2. Kristian Nikolov
    Admin
    Kristian Nikolov avatar
    206 posts

    Posted 02 Dec 2013 Link to this post

    Hi Silvio,

    If an object is still managed by its context you can detach it without any of its related objects, even if they have been previously loaded in memory.

    To do that you can use the overload of CreateDetachedCopy which only takes one argument - T entity. Consider the following example:
    using (EntitiesModel context = new EntitiesModel())
    {
        Car originalCar = context.Cars.FirstOrDefault();
        Car detachedCar = context.CreateDetachedCopy(originalCar);
        Debug.Assert(detachedCar.RentalOrders.Count == 0);
        Debug.Assert(detachedCar.Category == null);
     
        Car attachedCar = context.AttachCopy(detachedCar);
        Debug.Assert(attachedCar.RentalOrders.Count == 0);
        Debug.Assert(attachedCar.Category == null);
    }

    The Car entity has a reference property Categories and a reference collection RentalOrders. CreateDetachedCopy(T entity) detaches the entity without any of its navigation properties - the reference collection RentalOrders of detachedCar is empty and its reference property Category is null. You can then attach the detached car without its navigation properties.

    On the other side if you are attaching a newly created object, or are making any changes to the detached object, you will have to manually assure that its references to related objects are not initialized.

    I hope this helps. If you have more questions do not hesitate to post in our forums again.

    Regards,
    Kristian Nikolov
    Telerik
    OpenAccess ORM Q3 2013 simplifies your model operations even further providing you with greater flexibility. Check out the list of new features shipped with our latest release!
  3. DevCraft banner
  4. Silvio Silva Junior
    Silvio Silva Junior avatar
    100 posts
    Member since:
    Mar 2010

    Posted 02 Dec 2013 Link to this post

    Hello Kristian.

    Thanks for your answer. Unfortunately, this is not working for me. I followed your example, but, my attached objects are still being saved.

    Look at my code:
    EntitiesModel1 context = new EntitiesModel1();
     
    CanalComunicacao original = context.CanalComunicacaos.FirstOrDefault(); //main obj
    original.CanalComunicacaoTipo.Descricao = "abcdefg"; //attached obj
     
    CanalComunicacao detached = context.CreateDetachedCopy(original);
     
    Debug.Assert(detached.CanalComunicacaoTipo == null);
     
    CanalComunicacao attached = context.AttachCopy(detached);
     
    Debug.Assert(attached.CanalComunicacaoTipo == null);
     
    context.SaveChanges();


    My second Debug.asset statement have failed.

    What is wrong with my code?

    Regards;
  5. Kristian Nikolov
    Admin
    Kristian Nikolov avatar
    206 posts

    Posted 03 Dec 2013 Link to this post

    Hi Silvio,

    It seems that I have mislead you by not explaining correctly the provided code sample. Please excuse me for the inconvenience caused.

    The behavior your code exhibits is normal and expected of Telerik OpenAccess ORM.

    When using the CreateDetachedCopy(T entity) method, the returned object is indeed detached without its navigation properties. However when the object is attached to a context, its navigation properties will be automatically resolved if possible.

    As for the changes which are being saved - modifying the original object causes changes to its context. For this reason the context already has changes made to it before attaching the object to it. You can verify that by using the .HasChanges property of the context.

    If you have further questions, could you please provide us with more details about your use case? Answering the following questions would help us better advise you on how to use our Attach/Detach API:
    • Are you attaching the object to the same context from which it has been detached?
    • Are you making modifications to the original or the detached object before using the AttachCopy method?
    • What is the functionality you are trying to achieve using the Attach/Detach API?

    We are looking forward to your feedback.


    Regards,
    Kristian Nikolov
    Telerik
    OpenAccess ORM Q3 2013 simplifies your model operations even further providing you with greater flexibility. Check out the list of new features shipped with our latest release!
  6. Silvio Silva Junior
    Silvio Silva Junior avatar
    100 posts
    Member since:
    Mar 2010

    Posted 07 Dec 2013 Link to this post

    Thanks Kristian. I'm attaching to the same dbcontext.
    I'm using UnitOfWork pattern.

    Yes, I'm making modifications to the original object before pass it to update.

    I'm only trying to update an entity, and only the specific entity (not the attached entities).

    Regards.
  7. Kristian Nikolov
    Admin
    Kristian Nikolov avatar
    206 posts

    Posted 10 Dec 2013 Link to this post

    Hi Silvio,

    It appears that the situation is more related to the way OpenAccess handles transactions and pushes changes to the database.

    When making changes to entities, they are added to a transaction which is associated with the context which manages them. You can commit the transaction using SaveChanges(), rollback the transaction using ClearChanges() or flush the changes without completing the transaction using FlushChanges().

    What this means is that in order to push only a certain set of changes (in your case only those made to the specific entity) to the database, you have to have only that set of changes in your transaction at the moment when you use SaveChanges() or FlushChanges().

    Since in your case, by making changes to the original object you are introducing changes in the context and then attaching the detached object to that same context, you will have to manually assure that the context has only those changes which you wish to commit (the changes only to the core entity) before using SaveChanges() or FlushChanges().

    You can use the HasChanges property and the GetChanges() method to verify whether there are any pending changes and check what they are.

    I hope this helps.

    Regards,
    Kristian Nikolov
    Telerik
    OpenAccess ORM Q3 2013 simplifies your model operations even further providing you with greater flexibility. Check out the list of new features shipped with our latest release!
Back to Top
DevCraft banner