我有一个 Blazor EditForm,我使用模型将其与对象关联并绑定控件。
EditForm 模型 =“@Client”OnValidSubmit =“SubmitForm”
当用户想要编辑模型时,我使用 EF Core 从模型中获取数据,
var Client = _dbContext.Set().FindAsync(id);
但是,当用户进入编辑一个Client并更改了一条数据,然后没有按保存按钮而没有保存而离开表单时,如果他返回表单编辑同一条记录,则被修改的字段不保存会显示用户捕获的数据,这是因为 EF Core 进行了跟踪。
如果我将代码更改为 var client = _dbContext.Set().AsNoTracking().FirstOrDefaultAsync(c => c.ClientId == id),
EF Core 不再进行跟踪,这解决了问题。
我想知道这样做是否正确以及是否会影响我的系统的性能。
谢谢你。
您面临一些挑战:
您很可能已将
DbContext
注册为作用域,这是正确的,但 Blazor 不会自动创建作用域。这就是为什么文档强调使用 IDbContextFactory
。
但是,使用
IDbContextFactory
可能会使存储库的使用变得复杂,因为每个方法都需要创建和处置上下文。
在您的情况下,每个用户会话有一个
DbContext
会导致与同一会话触发的其他操作发生冲突。
如果您不想手动管理
IDbContextFactory
和 DbContext
资源(这是主观的),这里有两个选项:
不太理想:每次使用前清除
DbContext
状态:context.ChangeTracker.Clear()
。
好多了: 将
IServiceScopeFactory
注入控制器以手动创建范围。当您需要使用服务或存储库时,请使用 CreateScope()
,检索所需的服务,执行所需的方法,然后释放范围。
这是一个用 C# 编写的简化示例:
public class MyController
{
private readonly IServiceScopeFactory _scopeFactory;
public MyController(IServiceScopeFactory scopeFactory)
{
_scopeFactory = scopeFactory;
}
public void SomeControllerMethod()
{
// Any services or repositories registered with scope lifetime will be disposed of automatically
using var scope = _scopeFactory.CreateScope();
var someService = scope.ServiceProvider.GetRequiredService<SomeService>();
someService.DoSomeWork();
}
}