Blazor 服务器和实体框架.如何避免对数据库的多次冲突调用 [英] Blazor Server and the Entity Framework. How to avoid multiple conflicting calls to the DB

查看:11
本文介绍了Blazor 服务器和实体框架.如何避免对数据库的多次冲突调用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

总结

在我的 Razor 页面中,单个用户操作会触发两个事件.这些事件导致调用 EF,从而导致错误:

In my Razor page, a single user action fires off two events. These events result in calls to the EF which result in the error:

System.InvalidOperationException HResult=0x80131509 消息=A第二个操作在上一个操作之前在此上下文中启动完全的.这通常是由于不同的线程使用相同的DbContext 的实例.

System.InvalidOperationException HResult=0x80131509 Message=A second operation started on this context before a previous operation completed. This is usually caused by different threads using the same instance of DbContext.

设置我没有一个巨大的 DBContext,而是有多个上下文,每个上下文都专注于 DB 中的一小部分功能.所以,让我们想象一下,我在这里处理的是与 People 合作的功能.

Setup Rather than have one huge DBContext, I have multiple contexts, each focused on a small area of functionality in the DB. So, let's imagine that here I'm dealing with functionality for working with People.

因此,我有一个 PeopleContext 和一个 PeopleService.在我的启动中,这些注册为:

I therefore have a PeopleContext, and a PeopleService. In my startup, these are registered as:

services.AddDbContext<PeopleContext>();
services.AddScoped<PeopleService>();

并且上下文是依赖注入到服务中的:

And the Context is Dependency Injected into the Service:

public class PeopleService
{
    public PeopleService(PeopleContext context)
    {
        this.Context = context;
    }

    private PeopleContext Context { get; }

操作

想象一个页面,左侧有一个网格显示每个人的摘要,右侧有一个区域显示所选人员的详细信息.

So picture a page that has a grid on the left hand side showing a summary of each person, and an area on the right hand side where we show the details of the selected person.

当有人点击网格的一行时,我们会调用服务以加载该人的完整详细信息并在右侧显示该数据.

When someone clicks a row of a grid, we make a call to the Service to load the full details of that person and display that data in the right hand side.

我们在网格上还有一个 按钮.当有人点击它时,它会打开一个模式窗口.该窗口调用 SAME 服务上的 SAME 方法(因此使用 SAME 上下文)以加载完整的详细信息,以便我们可以编辑此人.

We also have an button on the grid. When someone clicks that, it opens up a modal window. That window makes a call the the SAME method on the SAME Service (therefore using the SAME Context) to load the full details so that we can edit the person.

所以,我的问题当然是当有人单击网格中的 按钮时,他们也在选择当前行,因此该方法几乎同时被调用两次,从而导致上述冲突.

So, my problem is of course that when someone clicks the button in the Grid, they're also selecting the current row and so that method gets called twice at almost the same time, resulting in the above conflict.

解决方案

我不认为我想引入锁定的概念,因为这会导致性能问题.我也不想在不同的服务中复制该方法,因为我想让我的代码保持干燥.我不确定当有人单击行上的按钮时不触发 SELECT ROW 事件是否有意义.我也不是第一个遇到这种情况的人,因此必须有针对此类行为的既定最佳实践"——因此这篇文章希望能发现那是什么.

I don't think that I want to intoduce the concept of locking because that can lead to performance issues. I also don't want to duplicate the method in a different Service because I want to keep my code DRY. I'm not sure it makes great sense to not fire the SELECT ROW event when someone clicks the button on the row. I also can't be the first person to come across this, so there must be an established "best practice" for this sort of behaviour - hence this post to hopefully discover what that is.

使用:Blazor 服务器,.NET 3.1

Using: Blazor Server, .NET 3.1

推荐答案

最终解决方案是:

剃刀页面

@inherits OwningComponentBase<Data.MyService>

启动

services.AddDbContext<MyContext>();
services.AddScoped<MyService>();

有关详细信息,请参阅:将 Entity Framework Core 与 Blazor #10448 结合使用

For more details, see: Using Entity Framework Core with Blazor #10448

这篇关于Blazor 服务器和实体框架.如何避免对数据库的多次冲突调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆