ASP.NET核心身份.使用ApplicationDbContext和UserManager.他们共享上下文吗? [英] ASP.NET Core Identity. Using ApplicationDbContext and UserManager. Do they share the context?
问题描述
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方法需要它呢?通过依赖项注入获得的ApplicationDbContext实例与CreateAsync使用的相同吗?
谢谢.
ASP.NET Core应用程序中Entity Framework Core的默认注册是每个请求的范围,因此它们将明确共享上下文.
从ASP.NET Core Identity的EF Core默认实现的源代码中可以看到( 和此处 ,它们都保存更改. 您遇到的问题是 当然,首选使用 async-all-the-way ,并且您不应该使用 i have an database initialization method in an ASP.NET MVC Core 2 application.
In that method i'm using ApplicationDbContext and UserManager to initialize the database.
I get both instances from the constructor's dependency injection: What i want to know is if they share the same context instance or if one context is created for ApplicationDbContext and another for UserManager.
If i execute something like this: The user is created at database inmediatly after the CreateAsync call. But, if then i update the user like this: After the call to UpdateAsync nothing is updated at the database. The name of the user stills being "test". But, if then i execute: The changes are applied and the database is updated. So, why the CreateAsync method "saves its changes" without explicitly calling "context.SaveChanges" and the UpdateAsync method needs it? Is the ApplicationDbContext instance i get by dependency injection the same that CreateAsync is using? Thank you. The default registration of Entity Framework Core in an ASP.NET Core application is a per-request scope, so they will definitively share the context. As you can see from the source code of the default implementation of EF Core for ASP.NET Core Identity (here and here , they both save changes. The problem you are experiencing is that you are not Of course, using async-all-the-way is the preferred version and you shouldn't block using 这篇关于ASP.NET核心身份.使用ApplicationDbContext和UserManager.他们共享上下文吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!/// <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
,因此您需要更改为:await userManager.UpdateAsync(adminTeacherUser);
//or
userManager.UpdateAsync(adminTeacherUser).Wait();
.Wait()
进行阻止.public static void Initialize(ApplicationDbContext context,
UserManager<ApplicationUser> user)
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();
adminTeacherUser.Name = "other";
userManager.UpdateAsync(adminTeacherUser);
context.SaveChanges();
/// <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
ing for the result of UpdateAsync
, so you need to change to:await userManager.UpdateAsync(adminTeacherUser);
//or
userManager.UpdateAsync(adminTeacherUser).Wait();
.Wait()
.