2016-05-04 8 views
0

Я Увеличенная ApplicationUser, добавив родительский объект:OptimisticConcurrencyException при удалении ApplicationUser, который имеет родителя

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; } 
} 

и связанный с ним DbContext ссылку на новой сущности

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

Теперь, когда я попробуйте удалить ApplicationUser, userManager.UpdateAsync() выдает 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 = "[email protected]", 
      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>(); 
    } 

Чтобы повторить, у моей модели данных нет элементов для проверки параллелизма. Вышеупомянутый код вырезается и вставляется из недавно созданного приложения MVC, которое я изменил, добавив родительский объект в объект ApplicationUser.

Другое примечание: при исследовании этой проблемы я столкнулся с SO-сообщением (которое я не могу найти сейчас) с нескольких лет назад, которое утверждало, что это известная ошибка, так как Identity запутывается, когда пытается обновить и видит, что ничего (в родительской записи) не изменилось.

И еще одно примечание. Я попытался сделать внешний ключ MasterId нулевым и установить его значение null перед тем, как попытаться удалить пользователя. Не помогло. Проблема заключается в наличии внешнего ключа в объекте ApplicationUser, независимо от того, имеет ли значение FK значение.

+0

Вопрос: Почему вы делаете «UpdateAsync (user)» _after_ 'DeleteAsync (user)'? На самом деле, почему вы вообще называете «Update»? –

+0

@ ChrisCurtis Darned хороший вопрос, нет хорошего ответа. По какой-то причине я понял, что 'Delete (user)' работал как 'context.Users.Remove (user)', который не сохраняется в базе данных до тех пор, пока вы не назовете 'context.SaveChanges()'. Если вы будете так любезны, чтобы опубликовать свой комментарий в качестве ответа, я соглашусь с ним. Благодаря! –

+0

Таким образом, возникает очевидный вопрос: в каких сценариях мне нужно вызвать 'userManager.Update()'? «Документация» («Обновляет пользователя») совершенно бесполезна. Выполняют ли все подпрограммы UserManager свои изменения? Если я изменю свойства UserName или Email в объекте ApplicationUser, могу ли я просто вызвать DbContext.SaveChanges() или UserManager.Update сделать какую-то другую магию? Я думаю, все это было бы большим кормом для нового вопроса SO ... –

ответ

0

Звонок на UpdateAsync(user) не нужен, и, вероятно, это вызывает вашу проблему после DeleteAsync(user), так как пользователь был удален. Удалите вызовы обновления, и вы должны быть хорошими

+0

Просто делал, как запросил ОП. Я изменю его, чтобы ответить больше –

Смежные вопросы