Asp.net mvc 在新的ASP.NET MVC 6标识中,AspNetUsers表中ConcurrentySamp列的用途是什么?
在新的ASP.NET MVC 6标识中,Asp.net mvc 在新的ASP.NET MVC 6标识中,AspNetUsers表中ConcurrentySamp列的用途是什么?,asp.net-mvc,concurrency,database-schema,identity,asp.net-core-mvc,Asp.net Mvc,Concurrency,Database Schema,Identity,Asp.net Core Mvc,在新的ASP.NET MVC 6标识中,AspNetUsers表中的ConcurrencyStamp列的用途是什么 这是AspNetUsers表的数据库架构: 它也位于AspNetRoles表中: 我记得它不在ASP.NETMVC5标识中 到目前为止,我注意到它似乎有GUID值,因为它是用以下代码定义的: /// <summary> /// A random value that must change whenever a user is persisted to the st
AspNetUsers
表中的ConcurrencyStamp
列的用途是什么
这是AspNetUsers
表的数据库架构:
它也位于AspNetRoles
表中:
我记得它不在ASP.NETMVC5标识中
到目前为止,我注意到它似乎有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();
//
///一个随机值,每当用户被持久化到存储时,该值必须更改
///
公共虚拟字符串ConcurrencyStamp{get;set;}=Guid.NewGuid().ToString();
但是,这些文档不足以让我理解在什么情况下使用它。
//
///一个随机值,每当角色被持久化到存储时,该值都应该更改
///
公共虚拟字符串ConcurrencyStamp{get;set;}=Guid.NewGuid().ToString();
基本上,按照它的名字来看。用于标识数据当前版本的戳记。如果你改变它,邮票也会改变
因此,如果两个并发更新同时出现,它们必须具有相同的标记,否则其中一个应该被丢弃
因此命名为
ConcurrencyStamp
跟进Maxime的回复:
如果查看OnModelCreating()方法中IdentityDbContext的实现,您会发现:
builder.Entity<TUser>(b =>
{
....
b.Property(u => u.ConcurrencyStamp).IsConcurrencyToken();
....
因此,它确实做了它应该做的事情:防止用户对象上的并发更新。该令牌仅在ASP Identity EntityFramework模块中“隐藏”使用。基本上,如果发生一个用户对象的并发更新,DB上下文将抛出DbUpdateConcurrencyException。作为名称状态,用于防止并发更新冲突 例如,数据库中有一个名为彼得的
UserA
2名管理员打开UserA
的编辑器页面,希望更新此用户
Admin_1
打开页面,看到一个名为Peter的用户Admin_2
打开页面,看到一个名为Peter的用户(显然)Admin_1
将用户名更新为Tom,并保存数据。现在UserA
在名为Tom的数据库中Admin_2
将用户名更新为Thomas,并尝试保存它ConcurrencyStamp
,当Admin_1
/Admin_2
加载页面时,将加载戳。更新数据时,此戳记也将更改。
因此,现在第5步将是系统抛出异常,告诉管理员2此用户已经更新,因为他
ConcurrencyStamp
与他加载的不同。认识到这实际上是一个数据层功能也很重要。标识的模式,但实际上没有使用它
标识代码库中没有任何逻辑——只有当EFCore真正去保存它时,它才会生效
我将假设(尚未使用v6),顾名思义,它用于处理
用户的并发更新。我手动将类似的内容(例如,rowversion
/时间戳
)添加到。嗯…我开始觉得这是为了ASP.NET缓存的目的。我想知道的是,为什么他们会将它设置为nvarchar(MAX)
,如果它不会超过GUID@MichaelTranchida我猜是跨平台/数据库。此外,您还可以将其存储在甚至不是SQL数据库的地方。添加了更多信息。很抱歉缺乏咖啡因。“两次同步更新…必须具有相同的标记”不正确/完整。任何更新都必须与存储中的行具有相同的戳记。如何在控制器中检查此戳记?就像在编辑控制器中一样,我会编写database.id==model.id&&database.stamp==model.stamp,然后更新else错误。这是检查的方法吗?请确认,谢谢
Context.Update(user);
try
{
await SaveChanges(cancellationToken);
}
catch (DbUpdateConcurrencyException)
{
return IdentityResult.Failed(ErrorDescriber.ConcurrencyFailure());
}