簡體   English   中英

ASP.NET核心身份。 使用ApplicationDbContext和UserManager。 他們是否分享背景?

[英]ASP.NET Core Identity. Using ApplicationDbContext and UserManager. Do they share the context?

我在ASP.NET MVC Core 2應用程序中有一個數據庫初始化方法。 在該方法中,我使用ApplicationDbContext和UserManager來初始化數據庫。 我從構造函數的依賴注入中獲取了兩個實例:

public static void Initialize(ApplicationDbContext context,
            UserManager<ApplicationUser> user)

我想知道的是,如果它們共享相同的上下文實例,或者為ApplicationDbContext創建了一個上下文,而為UserManager創建了另一個上下文。 如果我執行這樣的事情:

ApplicationUser adminTeacherUser = new ApplicationUser
            {
                UserName = "test@test.com",
                Email = "test@test.com",
                EmailConfirmed = true,
                Name = "test",
                LastName = "test",
                BirthDate = null,
                EntryDate = DateTime.Now                    
            };

            userManager.CreateAsync(adminTeacherUser, "password").Wait();

在CreateAsync調用之后,用戶在數據庫中創建。

但是,如果那時我像這樣更新用戶:

adminTeacherUser.Name = "other";                
userManager.UpdateAsync(adminTeacherUser);

調用UpdateAsync后,數據庫中不會更新任何內容。 用戶名仍然是“測試”。

但是,如果那時我執行:

context.SaveChanges();

將應用更改並更新數據庫。

那么,為什么CreateAsync方法“保存其更改”而不顯式調用“context.SaveChanges”並且UpdateAsync方法需要它? ApplicationDbContext實例是通過依賴注入得到的,與CreateAsync使用的相同嗎?

謝謝。

ASP.NET Core應用程序中的Entity Framework Core的默認注冊是按請求范圍,因此它們將明確地共享上下文。

正如您可以從EF Core for ASP.NET Core Identity的默認實現的源代碼中看到的( 這里

/// <summary>
/// Creates the specified <paramref name="user"/> in the user store.
/// </summary>
/// <param name="user">The user to create.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> used to propagate notifications that the operation should be canceled.</param>
/// <returns>The <see cref="Task"/> that represents the asynchronous operation, containing the <see cref="IdentityResult"/> of the creation operation.</returns>
public async override Task<IdentityResult> CreateAsync(TUser user, CancellationToken cancellationToken = default(CancellationToken))
{
    cancellationToken.ThrowIfCancellationRequested();
    ThrowIfDisposed();
    if (user == null)
    {
        throw new ArgumentNullException(nameof(user));
    }
    Context.Add(user);
    await SaveChanges(cancellationToken);
    return IdentityResult.Success;
}

在這里

/// <summary>
/// Updates the specified <paramref name="user"/> in the user store.
/// </summary>
/// <param name="user">The user to update.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> used to propagate notifications that the operation should be canceled.</param>
/// <returns>The <see cref="Task"/> that represents the asynchronous operation, containing the <see cref="IdentityResult"/> of the update operation.</returns>
public async override Task<IdentityResult> UpdateAsync(TUser user, CancellationToken cancellationToken = default(CancellationToken))
{
    cancellationToken.ThrowIfCancellationRequested();
    ThrowIfDisposed();
    if (user == null)
    {
        throw new ArgumentNullException(nameof(user));
    }

    Context.Attach(user);
    user.ConcurrencyStamp = Guid.NewGuid().ToString();
    Context.Update(user);
    try
    {
        await SaveChanges(cancellationToken);
    }
    catch (DbUpdateConcurrencyException)
    {
        return IdentityResult.Failed(ErrorDescriber.ConcurrencyFailure());
    }
    return IdentityResult.Success;
}

,他們都保存了變化。

您遇到的問題是您沒有await UpdateAsync的結果,因此您需要更改為:

await userManager.UpdateAsync(adminTeacherUser);
//or
userManager.UpdateAsync(adminTeacherUser).Wait();

當然,使用async-all-the-way是首選版本,您不應該阻止使用.Wait()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM