Entries in Join Table being Deleted

2 posts, 0 answers
  1. Braden
    Braden avatar
    12 posts
    Member since:
    Oct 2012

    Posted 22 Jan 2014 Link to this post

    I'm having a problem with entries in a join table being deleted.  Here is the situation:

    I'm operating in an n-tier environment, so there is a service layer (.NET Web API) that pulls objects out of the database and serializes (JSON) them back to a client. The client then makes any changes it needs and serializes them back to the service layer which just attaches the object and calls SaveChanges.  When the service layer is serializing data, it creates a detached copy of only the pieces of the object it needs.

    So, let's say that I have 3 object types: Users, Emails, and Claims. Emails has a foreign key back to Users, so it's just a one-to-many relationship.  Users and Claims are joined together in a many-to-many relationship using a join table (UserClaims). When the User object is serialized back and forth, the Emails and Claims are not included (they were never detached), so they are just serialized as empty lists ("[]"). When the User object is reattached in the service layer and SaveChanges is called, the Emails are left alone, even though they weren't present in the User object before reattaching, but the Claims objects are deleted from the join table. It seems to me like these should be working the same, but they're not. I also don't know if there's a way to look up whether there are any pending changes on the UserClaims table since it's not a real type in OpenAccess that can be passed to context.GetChanges().GetDeletes<>(), just a hidden join table. The only way I know that this is where they are getting deleted is by tracking the SQL that is being generated.

    Is there anything that I can do to convince OpenAccess to leave the Claims alone without having to always serialize the Claims with the User objects?
  2. Viktor Zhivkov
    Admin
    Viktor Zhivkov avatar
    291 posts

    Posted 27 Jan 2014 Link to this post

    Hi Braden,

    I am sorry for the inconvenience that you have experienced.
    The issue that you have described is a newly reported bug that we are considering as serious fault and we will do our best to fix it for the up-coming Q1 2014 release.
    Until the fix is available you can use the following work around to stop join-table records from being cleared:
    1. Extend your concrete repository with a partial class. You should do that for any entity type that has many-to-many association(s). In your scenario at least UsersRepository and ClaimsRepository should be extended.
    2. Override the Update(...) method in the new partial code file in the following manner: 
      01.public partial class UserRepository
      02.{
      03.    public override User Update(User entity)
      04.    {
      05.        if (entity == null)
      06.            throw new ArgumentNullException("entity");
      07. 
      08.        // load the target entity from database
      09.        User loadedEntity = dataContext.GetAll<User>().FirstOrDefault(entity.UserId);
      10.        if (loadedEntity == null)
      11.            throw new ArgumentOutOfRangeException("Could not load user with the same ID");
      12. 
      13.        // manually apply the same changes to the loaded one
      14.        loadedEntity.UserName = entity.UserName;
      15.        loadedEntity.Password = entity.Password;
      16.        // TODO: set all relevant properties;
      17.        // do not set the Many-To-Many property unless you did some changes there!
      18. 
      19.        // persist the changes in loadedEntity
      20.        dataContext.SaveChanges();
      21. 
      22.        // return a detached copy back to the client
      23.        User detachedEntity = dataContext.CreateDetachedCopy(loadedEntity, fetchStrategy);
      24. 
      25.        return detachedEntity;
      26.    }
      27.}
    This work around will remove the issue with the Many-to-Many association, but is hard to maintain if you make modifications to the entity types that is handled by the controller and you have to manually code the setting of values from one instance to the other.
    I will make sure to notify you as soon as the build with the fix for this issue is publicly available so you can get back to the out of the box implementation of the repository.

    As a small compensation for the inconvenience and as recognition of reporting a new issue with our product I am adding 500 Telerik points to your account.

    Regards,
    Viktor Zhivkov
    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
Back to Top