在不同 dbcontext 的情况下使用实体框架出现并发错误

问题描述 投票:0回答:1

我有一个给定的实体“学生”,其在“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
    }
}

上述问题可以通过以下两种方式解决,各有优缺点:

  1. 使用一个 writer
    DbContext
    实例并将其用于读取和写入操作。
    缺点:这不是在读写数据库实例上分配负载的最佳方法,因为写入实例只有 1 个,但读取实例可以扩展到多个
  2. 编写
    SaveChangesAsync
    拦截器来注意更新 LastModified 值。
    缺点:拦截器的开销

使用实体框架处理基于应用程序的并发检查而不影响应用程序性能的更好方法是什么?

如果还有其他选项,请分享

c# postgresql performance entity-framework concurrency
1个回答
0
投票
如果在修改

SaveChangesAsync()

 的属性之前,使用 
studentToBeModified
 开始在编写器中跟踪它,
Attach()
将会成功。
你的

context

的身体会变成:

if

© www.soinside.com 2019 - 2024. All rights reserved.