Answered by:
Problem with IdentityUserRoles

Question
-
User1287536547 posted
I am trying to extend the IdentityUser class:
public class User : IdentityUser { public Address Address { get; set; } }//end of class User
here is my DbContext class:
public class MembershipContext : IdentityDbContext<User> { protected override void OnModelCreating(System.Data.Entity.DbModelBuilder modelBuilder) { modelBuilder.ComplexType<Address>(); modelBuilder.Entity<IdentityUserRole>().HasKey(x => x.RoleId); modelBuilder.Entity<IdentityUserLogin>().HasKey(x => x.ProviderKey); } }//end of class MembershipContext
When Ef Generates the tables in the IdentityUserRoles table it creates a RoleId column, a UserId column and a IdentityRole_Id column, which when a user is add to a rolethe RoleId and IdentityRole_Id have the same value. If I remove a user it just sets the UserId and IdentityRole_Id to Null instead of removing the row. So if I try to add the User back to the same Role it throws an exception :
Unhandled Exception: System.Data.Entity.Infrastructure.DbUpdateException: An err
or occurred while saving entities that do not expose foreign key properties for
their relationships. The EntityEntries property will return null because a singl
e entity cannot be identified as the source of the exception. Handling of except
ions while saving can be made easier by exposing foreign key properties in your
entity types. See the InnerException for details. ---> System.Data.Entity.Core.U
pdateException: An error occurred while updating the entries. See the inner exce
ption for details. ---> System.Data.SqlClient.SqlException: Violation of PRIMARY
KEY constraint 'PK_dbo.IdentityUserRoles'. Cannot insert duplicate key in objec
t 'dbo.IdentityUserRoles'. The duplicate key value is (e16c7bdb-27c8-4b86-8804-6
2fb585230c1).
The statement has been terminated.
at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolea
n breakConnection, Action`1 wrapCloseInAction)
at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception
, Boolean breakConnection, Action`1 wrapCloseInAction)
at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObj
ect stateObj, Boolean callerHasConnectionLock, Boolean asyncClose)
at System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand
cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler,
TdsParserStateObject stateObj, Boolean& dataReady)
at System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, Run
Behavior runBehavior, String resetOptionsString)
at System.Data.SqlClient.SqlCommand.CompleteAsyncExecuteReader()
at System.Data.SqlClient.SqlCommand.EndExecuteNonQueryInternal(IAsyncResult a
syncResult)
at System.Data.SqlClient.SqlCommand.EndExecuteNonQueryAsync(IAsyncResult asyn
cResult)
at System.Threading.Tasks.TaskFactory`1.FromAsyncCoreLogic(IAsyncResult iar,
Func`2 endFunction, Action`1 endAction, Task`1 promise, Boolean requiresSynchron
ization)
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNot
ification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd(Task task)
at System.Data.Entity.Core.Mapping.Update.Internal.DynamicUpdateCommand.<Exec
uteAsync>d__0.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNot
ification(Task task)
at System.Data.Entity.Core.Mapping.Update.Internal.UpdateTranslator.<UpdateAs
ync>d__0.MoveNext()
--- End of inner exception stack trace ---
at System.Data.Entity.Core.Mapping.Update.Internal.UpdateTranslator.<UpdateAs
ync>d__0.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNot
ification(Task task)
at System.Data.Entity.Core.Objects.ObjectContext.<ExecuteInTransactionAsync>d
__3d`1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNot
ification(Task task)
at System.Data.Entity.Core.Objects.ObjectContext.<SaveChangesToStoreAsync>d__
39.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNot
ification(Task task)
at System.Data.Entity.SqlServer.DefaultSqlExecutionStrategy.<ExecuteAsyncImpl
ementation>d__9`1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNot
ification(Task task)
at System.Data.Entity.Core.Objects.ObjectContext.<SaveChangesInternalAsync>d_
_31.MoveNext()
--- End of inner exception stack trace ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNot
ification(Task task)
at Microsoft.AspNet.Identity.EntityFramework.UserStore`6.<SaveChanges>d__31.M
oveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNot
ification(Task task)
at Microsoft.AspNet.Identity.EntityFramework.UserStore`6.<UpdateAsync>d__12.M
oveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNot
ification(Task task)
at Microsoft.AspNet.Identity.UserManager`2.<UpdateAsync>d__5.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNot
ification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd(Task task)
at Microsoft.AspNet.Identity.UserManager`2.<AddToRoleAsync>d__86.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNot
ification(Task task)
at Microsoft.AspNet.Identity.AsyncHelper.RunSync[TResult](Func`1 func)
at Microsoft.AspNet.Identity.UserManagerExtensions.AddToRole[TUser,TKey](User
Manager`2 manager, TKey userId, String role)
at Driver.Program.Main(String[] args) in c:\Users\Michael\Desktop\ALL_OnlyInC
ode\OnlyInCode\Driver\Program.cs:line 33
Why is it generating this table like this. Is there a configuration I can do to change this?
Thanks in advance!
Saturday, May 3, 2014 2:55 PM
Answers
-
User-734925760 posted
Hi,
According to your description, as you try to remove one record, it will not be delete, but updated and I think the RoleID field is primary key, so as you insert one record with the same roleID, it will throw error message.
I suggest you deleting the whole record as you want to delete one user. Please refer to the link below about deleting records from Entity Framework Table:
http://www.dotnetcurry.com/showarticle.aspx?ID=619
If you do not delete the rocords, I suggest you using update not insert.
Hope it's useful for you.
Best Regards,
Michelle Ge
- Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
Monday, May 5, 2014 4:37 AM