Iva*_*ono 5 c# asp.net-mvc entity-framework-core asp.net-core
目前,我在插入/更新实体时正在执行以下操作:
public async Task<IdentityResult> UpdateAsync(Model model, CancellationToken ct = default)
{
var entity = await GetAsync(ct);
if (entity == null)
{
return await CreateAsync(model, ct);
}
context.Entry(entity).State = EntityState.Detached;
Update(model);
model.ConcurrencyToken = Guid.NewGuid().ToString();
await context.SaveChangesAsync();
return IdentityResult.Success;
}
Run Code Online (Sandbox Code Playgroud)
以及更新方法:
protected virtual T Update(T entity)
{
var dbEntityEntry = context.Entry(entity);
if (dbEntityEntry.State == EntityState.Detached)
{
dbSet.Attach(entity);
dbEntityEntry.State = EntityState.Modified;
}
return entity;
}
Run Code Online (Sandbox Code Playgroud)
这是有效的。但是有没有更好的(通用)方法来处理并发?
Cod*_*und 11
是的,EF Core 中有一种管理并发的通用方法。您已经通过添加一列来完成第一部分,该列将管理每次更新的行版本,但您正在手动更新并发令牌。
最好的方法是让数据库通过使用自动为您更新并发令牌Timestamp。如EF Core 文档中所述:
时间戳/行版本是每次插入或更新行时数据库自动生成新值的属性。该属性还被视为并发令牌,确保如果您正在更新的行自查询以来发生了更改,您会收到异常。精确的细节取决于所使用的数据库提供商;对于SQL Server,通常使用byte[]属性,它将被设置为数据库中的ROWVERSION列。
如何使用它(EF Core 文档中的示例):
public class Blog
{
public int BlogId { get; set; }
public string Url { get; set; }
[Timestamp]
public byte[] Timestamp { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
因此不必更新Timestamp或ConcurrencyCheck列,因为数据库会为您完成此操作。
最后一部分是确保正确处理并发冲突并让用户知道他/她已经过时了。如何管理并发冲突(它们引发异常)。您可以按照此处的说明进行操作。
另请查看本教程。
| 归档时间: |
|
| 查看次数: |
12756 次 |
| 最近记录: |