gpt4 book ai didi

c# - ASP.NET 核心标识。使用 ApplicationDbContext 和 UserManager。他们共享上下文吗?

转载 作者:太空狗 更新时间:2023-10-29 22:56:52 26 4
gpt4 key购买 nike

我在 ASP.NET MVC Core 2 应用程序中有一个数据库初始化方法。在那个方法中,我使用 ApplicationDbContext 和 UserManager 来初始化数据库。我从构造函数的依赖注入(inject)中获得了两个实例:

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 后,数据库中没有更新任何内容。用户名仍然是“test”。

但是,如果我执行:

context.SaveChanges();

应用更改并更新数据库。

那么,为什么 CreateAsync 方法“保存其更改”而不显式调用“context.SaveChanges”而 UpdateAsync 方法需要它?我通过依赖注入(inject)获得的 ApplicationDbContext 实例与 CreateAsync 使用的相同吗?

谢谢。

最佳答案

在 ASP.NET Core 应用程序中 Entity Framework Core 的默认注册是每个请求范围,因此它们最终将共享上下文。

从 EF Core for ASP.NET Core Identity 的默认实现源代码可以看出(here

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

here

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

,它们都保存更改。

您遇到的问题是您没有等待UpdateAsync 的结果,因此您需要更改为:

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

当然,使用async-all-the-way 是首选版本,您不应阻止使用.Wait()

关于c# - ASP.NET 核心标识。使用 ApplicationDbContext 和 UserManager。他们共享上下文吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48519780/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com