Object.RelatedObject.Remove - not working?

9 posts, 1 answers
  1. Marko Gluhak
    Marko Gluhak avatar
    68 posts
    Member since:
    Apr 2006

    Posted 23 Dec 2015 Link to this post

    Hi,

     I have implement identity using Telerik Data Access (folowing some articles on net). In method RemoveLoginAsync this is the code that was looking ok for me:

    cUserLogin loginEntity = user.UserLogins.SingleOrDefault( l => l.LoginProvider == provider && l.ProviderKey == key );

    if ( loginEntity != null )
    {
        user.UserLogins.Remove( loginEntity );
        _db.SaveChanges( );
    }

     At my surpise this does not work. SaveChanges method does nothing. I also try to use (context.GetContext(user).SaveChanges(), context.GetContext(loginEntity).SaveChanges()) but nothing happen. I also checked if _db context is same as user context and it is. I also checked that user.UserLogins had 1 record before .Remove method call. After .Remove call it had 0 records. Still, SaveChanges method did not save anything.

    Only way I could manage this is to use this code:

     .....
    {
        _db.Delete(loginEntity);
        _db.SaveChanges();
    }

    My question is why is upper solution not working?

    Marko
  2. Marko Gluhak
    Marko Gluhak avatar
    68 posts
    Member since:
    Apr 2006

    Posted 23 Dec 2015 in reply to Marko Gluhak Link to this post

    I'm still using 2015 Q1 because of visual designer.
  3. DevCraft banner
  4. Marko Gluhak
    Marko Gluhak avatar
    68 posts
    Member since:
    Apr 2006

    Posted 23 Dec 2015 in reply to Marko Gluhak Link to this post

    Correction. I done this project from strach so I use nuget ackages and started to learn Fluent way. So I'm using 2015 Q3.
  5. Yavor Slavchev
    Admin
    Yavor Slavchev avatar
    22 posts

    Posted 24 Dec 2015 Link to this post

    Hello Marko ,
    Thank you for using our services.

    These are two different scenarios.
    In the first scenario, you are removing an item from the 'UserLogins' collection of the 'user' object. This means that you are basically changing the association between the objects thus, one login less for this particular user. In other words, the 'cUserLogin' object is not deleted from the database, it is just no longer associated to the specified user object.
    In the second scenario, the 'cUserLogin' object is deleted directly from the database and this is the correct way of deleting entities from the database using Telerik Data Access. Look at this article for more information about this.
    Note that for the first scenario to get the code working, you need to change the mapping configuration of the 'user.UserLogins' property to include a call to the IsManaged method. For more information, read How to: Manage One-to-Many Association.

    I hope this information is helpful.

    Regards,
    Yavor Slavchev
    Telerik
     
    Check out the latest announcement about Telerik Data Access vNext as a powerful framework able to solve core development problems.
  6. Marko Gluhak
    Marko Gluhak avatar
    68 posts
    Member since:
    Apr 2006

    Posted 24 Dec 2015 in reply to Yavor Slavchev Link to this post

    Hi,

    thanx for sharing this. If I follow what you just wrote, what should happen in DB when I call user.Logins.Remove(Login) method and after that call SaveChanges()?

    I can think of 2 scenarios:
    1. IdUser for that login wants to be set to NULL (but its not possible as it is not nullable field). In this case I should get exception or something?
    2. Object (login) is only removed from user in memory. But if both are persistant classes (user and uerlogin and has associations in mapping configuration, but did not had IsManaged) why its not somehow reflected to DB

    Thanx for answer.

    Marko

  7. Yavor Slavchev
    Admin
    Yavor Slavchev avatar
    22 posts

    Posted 24 Dec 2015 Link to this post

    Hi Marko ,
    Thank you for getting back to us.

    If the associations for the both entities have the IsManaged() set, the runtime would actually try to set the associated field to NULL when it is removed  from the collection and this will throw an exception if the field is not nullable.
    If IsManaged() is not set for the associations, then the database will not be affected at all. This also applies for the insert statements, as the key property will not be set in this case.
    In order to remove an entity from the database, you should always make sure to use the Delete() method of the context, regardless if the IsManaged() is set or not.

    I hope this information is helpful.

    Regards,
    Yavor Slavchev
    Telerik
     
    Check out the latest announcement about Telerik Data Access vNext as a powerful framework able to solve core development problems.
  8. Marko Gluhak
    Marko Gluhak avatar
    68 posts
    Member since:
    Apr 2006

    Posted 24 Dec 2015 in reply to Yavor Slavchev Link to this post

    OK. Clear now.

    Just one more thing. What is right way (if IsManaged is set on both sides):

    1. can I delete userlogin using: context.Delete(user.UserLogins[0]) and then use context.SaveChanges().
    Will this delete desired UserLogin from DB and also from user.UserLogin Collection?

    2. I have user.UserLogins collection (2 records). I  get exact userLogin from DB and use context.Delete(userLogin) and after that context.SaveChanges(). This is way that you told is always better. My question here is what will happen to user.UserLogins collection when I delete userlogin in this way (will it automaticaly also somehow knows to remove it from collection or I need to manualy do it with user.UserLogins.Remove(userLogin)

     Marko

  9. Answer
    Yavor Slavchev
    Admin
    Yavor Slavchev avatar
    22 posts

    Posted 24 Dec 2015 Link to this post

    Hi Marko ,

    1. Yes, this will delete the first login from the UserLogins collection and will also update the collection even before SaveChanges() is invoked. Telerik Data Access runtime is keeping track of its objects and thats why these changes are reflected immediately.
    2. Basically the same here. It doesn't matter how you will pick which item you want to delete from the collection. It should be get from the same context anyway but then, the collection itself will always be refreshed after the Delete() method of the context is invoked with this item.

    Let me know if you have further questions.

    Regards,
    Yavor Slavchev
    Telerik
     
    Check out the latest announcement about Telerik Data Access vNext as a powerful framework able to solve core development problems.
  10. Marko Gluhak
    Marko Gluhak avatar
    68 posts
    Member since:
    Apr 2006

    Posted 24 Dec 2015 in reply to Yavor Slavchev Link to this post

    Thank you!

    Marko

Back to Top
DevCraft banner