Nik*_*tov 43 asp.net-mvc concurrency identity database-schema asp.net-core-mvc
新ASP.NET MVC 6标识中表中ConcurrencyStamp
列的用途是什么AspNetUsers
?
这是AspNetUsers
表的数据库模式:
它也在AspNetRoles
表中:
我记得在ASP.NET MVC 5中没有它.
到目前为止我注意到它似乎有GUID值,因为它使用以下代码定义:
/// <summary>
/// A random value that must change whenever a user is persisted to the store
/// </summary>
public virtual string ConcurrencyStamp { get; set; } = Guid.NewGuid().ToString();
Run Code Online (Sandbox Code Playgroud)
但是这个文档不足以让我理解它在哪种情况下使用.
Ste*_*.Xi 59
作为名称状态,它用于防止并发更新冲突.
例如,在数据库中有一个名为Peter的UserA 2管理员打开UserA的编辑器页面,想要更新该用户.
如果没有ConcurrencyStamp会发生什么,Admin_1的更新将覆盖Admin_1的更新.但由于我们有ConcurrencyStamp,当Admin_1/Admin_2加载页面时,会加载戳记.更新数据时,此标记也将更改.所以现在第5步将是系统抛出异常,告诉Admin_2该用户已经更新,因为他的ConcurrencyStamp与他加载的不同.
Max*_*ler 12
/// <summary>
/// A random value that should change whenever a role is persisted to the store
/// </summary>
public virtual string ConcurrencyStamp { get; set; } = Guid.NewGuid().ToString();
Run Code Online (Sandbox Code Playgroud)
基本上,看它命名.用于标识当前数据版本的戳记.如果你改变它,那么印章也是如此.
因此,如果两个并发更新同时进入,则它们必须具有相同的标记,否则应丢弃其中一个.
因此,名字,ConcurrencyStamp
.
同样重要的是要意识到这实际上是一个数据层功能。Identity 的架构将该列定义为并发列,但实际上并未使用它。
Identity 代码库内部没有任何逻辑——只有当 EFCore 真正去保存它时,它才会启动。
https://docs.microsoft.com/en-us/ef/core/modeling/concurrency
EF 代码优先 - IsConcurrencyToken()
小智 5
跟进Maxime的回复:
如果您在OnModelCreating()方法中查看IdentityDbContext的实现,则会发现:
builder.Entity<TUser>(b =>
{
....
b.Property(u => u.ConcurrencyStamp).IsConcurrencyToken();
....
Run Code Online (Sandbox Code Playgroud)
并在UserStore.UpdateAsync(...)方法中:
Context.Update(user);
try
{
await SaveChanges(cancellationToken);
}
catch (DbUpdateConcurrencyException)
{
return IdentityResult.Failed(ErrorDescriber.ConcurrencyFailure());
}
Run Code Online (Sandbox Code Playgroud)
因此,它确实可以实现预期的功能:防止对用户对象进行并发更新。令牌仅在ASP Identity EntityFramework模块中“在后台”使用。基本上,如果发生一个用户对象的并发更新,则数据库上下文将引发DbUpdateConcurrencyException。