使用 EF Core 获取 EditForm 数据(带或不带跟踪)的正确方法是什么?

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

我有一个 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 不再进行跟踪,这解决了问题。

我想知道这样做是否正确以及是否会影响我的系统的性能。

谢谢你。

asp.net-core entity-framework-core blazor editform
1个回答
0
投票

您面临一些挑战:

您很可能已将

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();
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.