问题
As the title says I am using the new C#
MVC 5
Identity
doing a simple call:
UserManager.AddToRole(User.Id, User.RequestedRole);
I am doing this in a method of my ViewModel
that is called from the Controller
The UserManager
is created in the Base Class
of my ViewModel
like this:
UserManager = new UserManager<TMUser>(new UserStore<TMUser>(new TMContext()));
When I make the above call to AddToRole
method, I get this Inner Exception
(The outer one is generic/useless):
{"A relationship from the 'Ledger_User' AssociationSet is in the 'Deleted' state. Given multiplicity constraints, a corresponding 'Ledger_User_Source' must also in the 'Deleted' state."}
I'm obviously not deleting anything at all but only adding a role to my user. I've had this exception before when I am trying to mix objects from multiple contexts...but I'm not doing that here...please help.
EDIT: I've gotten rid of the model in case it was interfering and added the following code to my controller:
public ActionResult UpdateRoles(string id)
{
if (ModelState.IsValid)
{
var userManager = new UserManager<TMUser>(new UserStore<TMUser>(new TMContext()));
var userRequestingRole = userManager.FindById(id);
if (!userManager.IsInRole(userRequestingRole.Id, userRequestingRole.RequestedRole))
userManager.AddToRole(userRequestingRole.Id, userRequestingRole.RequestedRole);
// It is still crashing with the same error in the above AddToRole
}
For further information, here is the structure of my TMUser
and Ledger
objects:
public class TMUser : IdentityUser
{
public TMUser()
{
Ledger = new Ledger();
OrderHistory = new List<Order>();
Clients = new List<Client>();
IsActive = true;
}
[DisplayName("Full Name")]
public string FullName { get; set; }
[DisplayName("Notification Email")]
public string NotificationEmail { get; set; }
public virtual Ledger Ledger { get; set; }
public virtual List<Order> OrderHistory { get; set; }
public virtual List<Client> Clients { get; set; }
public string RequestedRole { get; set; }
public virtual TMUser RoleApprovedBy { get; set; }
public bool IsActive { get; set; }
}
public class Ledger
{
public Ledger()
{
Transactions = new List<Transaction>();
}
public long Id { get; set; }
[Required]
public virtual TMUser User { get; set; }
public virtual List<Transaction> Transactions { get; set; }
public decimal GetBalance()
{
// ...
}
internal void AddTransaction(decimal amount, string description, Order order)
{
// ...
}
}
Another Edit:
Today was another frustrating day. After making some changes in my Context
it initially seemed like I fixed the problem. Here is the change I made:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<TMUser>().HasOptional(c => c.RoleApprovedBy);
modelBuilder.Entity<TMUser>().HasOptional(c => c.Ledger);
}
I added the above to the DB Context class, mine is: public class TMContext : IdentityDbContext<TMUser>
This worked the first time, I must have broken some kind of an association? However, when I tried again with a different user, a similar, but slightly different Exception
happened:
{"A relationship from the 'TMUser_Ledger' AssociationSet is in the 'Deleted' state. Given multiplicity constraints, a corresponding 'TMUser_Ledger_Target' must also in the 'Deleted' state."}
So it feels like I am back to square one...I can keep going by removing the Ledger
from the User
object, but that would be cheating...I really don't want to get hacky with it...please help...
回答1:
The problem is that you create a new Ledger in the constructor of the TMUser, when you do that you will remove the current ledger for the TMUser and replace it with a new empty one. And then, EF will handle the new Ledger as new object that needs to be inserted in the database. Thats why you are getting the validation error about an entity that is en deleted state.
Another thing with creating an new Ledger in the constructor of TMUser causes the effect that every TMUser has a ledger but in your database model you have set it to nullable (bacause of the HasOptional).
来源:https://stackoverflow.com/questions/23667190/identity-usermanager-addtorole-throws-exception