简体   繁体   中英

OptimisticConcurrencyException when deleting an ApplicationUser that has a parent

I've extended ApplicationUser by adding a parent entity:

public class ApplicationUser : IdentityUser
{
    public int MasterId { get; set; }
    public virtual Master Master { get; set; }
}

public class Master
{
    public int Id { get; set; }
    public string Name { get; set; }
}

And the related DbContext reference to the new entity

public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
    public DbSet<Master> Masters { get; set; }
}

Now, when I try to delete an ApplicationUser, userManager.UpdateAsync() throws an OptimisticConcurrencyException .

public class HomeController : Controller
{
    public async Task<ActionResult> Index()
    {
        // Get the DbContext and UserManager out of the OWIN pipeline
        var db = GetDbContext(this);
        var userManager = GetUserManager(this);

        // Create a Master record if necessary
        if (db.Masters.Count() == 0) {
            db.Masters.Add(new Master { Name = "The Master" });
            await db.SaveChangesAsync();
        }

        var masterId = (from m in db.Masters select m.Id).First();

        // Create a new ApplicationUser
        var user = new ApplicationUser {
            UserName = "Bob",
            Email = "abc@abc.com",
            MasterId = masterId
        };

        await userManager.CreateAsync(user, "Password123?");
        await userManager.UpdateAsync(user);

        // Try to delete the ApplicationUser
        user = (from u in db.Users select u).First();
        await userManager.DeleteAsync(user);
        await userManager.UpdateAsync(user); // Throws OptimisticConcurrencyException

        return View();
    }

    public static ApplicationDbContext GetDbContext(Controller controller)
    {
        return controller.HttpContext.GetOwinContext()
               .Get<ApplicationDbContext>();
    }

    public static ApplicationUserManager GetUserManager(Controller controller)
    {
        return controller.HttpContext.GetOwinContext()
               .GetUserManager<ApplicationUserManager>();
    }

Just to reiterate, my data model has no concurrency-checking members. The above code is cut-and-pasted from a newly created MVC app which I modified by adding a parent entity to the ApplicationUser entity.

Another note: In researching this issue, I ran across an SO post (which I can not find now) from several years ago that claimed that this is a known bug, to wit Identity gets confused when it tries to update the related records and sees that nothing (in the parent record) has changed.

And another note: I tried making the MasterId foreign key nullable, and set it to null before attempting to delete the user. Didn't help. The problem seems to be the presence of the foreign key in the ApplicationUser entity, whether or not the FK has a value.

The call to UpdateAsync(user) is not needed, and is probably causing your problem after the DeleteAsync(user) since the user has been deleted. Remove the update calls and you should be good

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM