当前,在插入/更新和实体时,我正在执行以下操作:
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;
}
以及更新方法:
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;
}
可以了 但是,有没有更好的(通用)方法来处理并发呢?
是的,在EF Core中有一种通用的并发管理方法。您已经通过添加一列来完成第一部分,该列将管理每次更新的行版本,但是您正在手动更新并发令牌。
最好的方法是让DB使用来自动为您更新并发令牌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; }
}
因此,不必更新Timestamp
orConcurrencyToken
列,因为它将由数据库为您完成。
最后一部分是确保正确处理并发冲突,并让用户知道他/她已经过时。如何管理并发冲突(它们引发异常)。您可以按照此处的说明进行操作。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句