entity-framework - Blazor 服务器和实体框架。如何避免对数据库的多次冲突调用
问题描述
概括
在我的 Razor 页面中,单个用户操作会触发两个事件。这些事件导致调用 EF 导致错误:
System.InvalidOperationException HResult=0x80131509 Message=在前一个操作完成之前在此上下文中启动了第二个操作。这通常是由使用相同 DbContext 实例的不同线程引起的。
设置 我没有一个巨大的 DBContext,而是有多个上下文,每个上下文都专注于数据库中的一小部分功能。所以,让我们想象一下,在这里我正在处理与 People 一起工作的功能。
因此,我有一个 PeopleContext 和一个 PeopleService。在我的启动中,这些注册为:
services.AddDbContext<PeopleContext>();
services.AddScoped<PeopleService>();
并且上下文被注入到服务中:
public class PeopleService
{
public PeopleService(PeopleContext context)
{
this.Context = context;
}
private PeopleContext Context { get; }
行动
因此,想象一个页面,左侧有一个网格,显示每个人的摘要,右侧有一个区域,我们显示所选人员的详细信息。
当有人单击网格的一行时,我们会调用服务以加载该人的全部详细信息并在右侧显示该数据。
我们在网格上还有一个 [Edit] 按钮。当有人点击它时,它会打开一个模式窗口。该窗口调用 SAME 服务上的 SAME 方法(因此使用 SAME 上下文)以加载完整的详细信息,以便我们可以编辑此人。
所以,我的问题当然是当有人点击 Grid 中的 [Edit] 按钮时,他们也在选择当前行,因此该方法几乎同时被调用两次,导致上述冲突。
解决方案
我不认为我想引入锁定的概念,因为这会导致性能问题。我也不想在不同的服务中复制该方法,因为我想让我的代码保持干燥。我不确定当有人单击行上的按钮时不触发 SELECT ROW 事件是否有意义。我也不能是第一个遇到这种情况的人,所以必须有一个既定的“最佳实践”来处理这种行为——因此这篇文章希望能发现那是什么。
使用:Blazor 服务器、.NET 3.1
解决方案
最终解决方案是:
剃刀页面
@inherits OwningComponentBase<Data.MyService>
启动
services.AddDbContext<MyContext>();
services.AddScoped<MyService>();
有关更多详细信息,请参阅:将 Entity Framework Core 与 Blazor #10448 一起使用
推荐阅读
- docker - 真正可复制的 Docker 容器?
- devise - 用户名/密码和 sso 系统 - sso 用户的密码值应该是多少
- vbscript - 如何通过 VBscript 获取 CAD 零件的位置?
- if-statement - 如何将 WHERE 函数添加到复杂字符串
- angular - 使用 ngfor 时如何处理数据以更快地显示
- python - 列名减半,数据用 pyodbc 和 Teradata 数据库编码错误
- java - Log4J 2 配置:如何同时按大小和按天拆分日志文件?
- javascript - 在第二次点击时触发 jquery 事件更新输入
- json - DStream JSON 对象到 SQLite
- python - Python Subprocess.Popen 带有声音警报的通知