我有一个给定的实体'学生'与基于应用程序的并发控制定义在'LastModified'。
public class Student
{
public int Id { get; set; }
public string Name { get; set; } = null!;
public DateTimeOffset Created { get; set; }
[ConcurrencyCheck]
public DateTimeOffset LastModified { get; set; }
}
字符串
现在,我在仓库层编写了更新函数,如下所示:
public async Task<UpsertResponse> UpdateAsync(Entities.Student student)
{
using var context = _dbContextFactory.CreateDbContext(readOnly: true); //Create reader DbContext instance
var studentToBeModified = await context.Student.FirstOrDefaultAsync(x => x.Id == student.Id).ConfigureAwait(false);
if (!studentToBeModified)
{
studentToBeModified.Name = student.Name;
studentToBeModified.LastModified = DateTimeOffset.UtcNow;
using var context = _dbContextFactory.CreateDbContext(readOnly: false); //Create writer DbContext instance
context.Update(studentToBeModified);
await context.SaveChangesAsync().ConfigureAwait(false); //Throws DbUpdateConcurrencyException
}
}
型
上述问题可以通过以下2种方式解决,并具有一些优点/缺点:
1.使用一个writer DbContext
示例,并将其用于读写操作。
缺点:这不是在读写数据库示例上分配负载的最佳方法,因为写示例只有1个,但读示例可以扩展到很多个
1.写SaveChangesAsync
拦截器来更新LastModified值。
缺点:Overhead to have an interceptor
使用实体框架处理基于应用程序的并发检查而不影响应用程序性能的更好方法是什么?
如果还有其他选择,请分享
1条答案
按热度按时间olmpazwi1#
如果在修改
studentToBeModified
的属性之前,您使用Attach()
在writercontext
中开始跟踪它,则SaveChangesAsync()
将成功。你的
if
的主体将变成:字符串