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();
}
Marko
8 Answers, 1 is accepted
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
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
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
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
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
Thank you!
Marko