DetectChanges при использовании AspNet.Identity UserManager - PullRequest
0 голосов
/ 30 августа 2018

Я использую AspNet.Identity для управления пользователями в своем проекте MVC, потому что я считаю, что это хорошее начало, теперь, когда он работает (с небольшими изменениями), я хотел добавить журнал аудита (Отслеживание изменений), как мой другой DbContext, который я использую.

В IdentityModel.cs у меня есть следующий код, который работает, но только в определенных ситуациях:

public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
    public ApplicationDbContext()
        : base("DefaultConnection", throwIfV1Schema: false)
    {
        //Can't recall if this was there by default
        Configuration.AutoDetectChangesEnabled = true;
    }

    public override int SaveChanges()
    {
        //Tell EF to Track Changes
        ChangeTracker.DetectChanges();

        //More code once I get this working
        //
    }

}

В моем контроллере у меня есть следующее:

[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Edit(EditUserViewModel editUser)
{
    var user = await UserManager.FindByIdAsync(editUser.Id);

    //Update a property within the User object
    user.FirstName = "Updated First Name";

    //Save to database
    var result = UserManager.Update(user);
    //The above saves to database, but doesn't trigger SaveChanges()

    //SaveChanges() will be triggered if I call
    HttpContext.GetOwinContext().Get<ApplicationDbContext>().SaveChanges();

}

Когда вызывается вышеуказанный HttpContext.GetOwinContext().Get<ApplicationDbContext>().SaveChanges();, обновленный ApplicationUser имеет EntityState, равный Unchanged. Имеет смысл, так как он уже был сохранен.

Однако я пытаюсь понять, как я могу использовать UserManager и по-прежнему работать с SaveChanges().

Я также понимаю, что мог бы написать класс, который бы регистрировал все это сам, но по мере расширения ApplicationUser (или ApplicationRole) я хотел бы избежать дополнительного кодирования для журнала аудита.

Любой совет или ссылки помогут!

1 Ответ

0 голосов
/ 25 февраля 2019

Установите AutoSaveChanges на false в конструкторе вашего UserStore (который вы передадите конструктору UserManager).

public class MyUserStore : UserStore<User, Role, int, UserLogin, UserRole, UserClaim>
    {
        private MyDbContext _context;
        public MyUserStore(MyDbContext context) : base(context)
        {
            //Set this to false
            AutoSaveChanges = false;
            _context = context;
        }
    }

Теперь вы можете вызвать сохранение изменений, как обычно, и трекер изменений будет содержать ожидаемые изменения.

Однако я столкнулся с исключительной ситуацией OptimisticConcurrencyException, когда пытался сделать более одного вызова UserManager между вызовами SaveChanges. Я просто вызывал SaveChanges после каждой операции UserManager.

...