【问题标题】:EF Core multiple HTTP requests throws an errorEF Core 多个 HTTP 请求引发错误
【发布时间】:2018-02-03 12:32:50
【问题描述】:

我似乎找不到这个问题的答案。

所以在前端,当用户加载页面时,我们会为该页面上的每个项目(10 个项目)调用一个 API。所以这等于 10 次 API 调用。

大多数调用都有效,但在尝试查询数据库时总是有一些调用失败,导致以下错误:

InvalidOperationException:第二个操作开始于此 前一个操作完成之前的上下文。任何实例成员 不保证是线程安全的。

现在我知道 Entity Framework 不是线程安全的,但我不确定如何解决这个错误。

在我使用 DBContext 的任何地方,它总是使用内置的 .net 核心 Ioc 容器注入。

这是 DI 设置

services.AddScoped<IOmbiContext, OmbiContext>();
services.AddTransient<ISettingsRepository, SettingsJsonRepository>();

根据这篇文章,我的所有存储库都设置在Transient 范围内,上下文为Scopedhttps://docs.microsoft.com/en-us/aspnet/core/data/entity-framework-6

现在我尝试将上下文更改为Transient,但它仍然会发生。

我怎样才能避免这种情况?

更多信息

API 方法:

[HttpGet("movie/info/{theMovieDbId}")]
public async Task<SearchMovieViewModel> GetExtraMovieInfo(int theMovieDbId)
{
    return await MovieEngine.LookupImdbInformation(theMovieDbId);
}

最终在抛出异常的地方调用以下代码:

public async Task<RuleResult> Execute(SearchViewModel obj)
{
    var item = await PlexContentRepository.Get(obj.CustomId); <-- Here
    if (item != null)
    {
        obj.Available = true;
        obj.PlexUrl = item.Url;
        obj.Quality = item.Quality;
    }
    return Success();
}

PlexContentRepository

public PlexContentRepository(IOmbiContext db)
{
    Db = db;
}

private IOmbiContext Db { get; }
public async Task<PlexContent> Get(string providerId)
{
   return await Db.PlexContent.FirstOrDefaultAsync(x => x.ProviderId == providerId); <-- Here
}

【问题讨论】:

  • @Nkosi 不,使用 asyncawait 关键字,所有内容都是完全异步的。
  • 您能否显示正在调用的引发错误的 API
  • @Nkosi 有很多代码,但我已经更新了我的问题以包含重要的部分。该软件是开源的,所以如果有人觉得有用,我可以包含一个 Github 项目的链接
  • 已经在查看 repo。 :)

标签: c# .net entity-framework asp.net-core entity-framework-core


【解决方案1】:

如果您使用 Entity Framework Core,通常不需要将数据库上下文添加为附加服务

我建议在Startup.cs 中设置您的 DbContext,如下所示:

services.AddEntityFrameworkSqlServer()
            .AddDbContext<OmbiContext>();

后面是一个控制器类,用于 API 调用,将 DBContext 作为构造函数参数。

public class ApiController : Controller
{
    protected OmbiContext ctx;
    public ApiController(OmbiContext dbctx)
    {
        ctx = dbctx;
    }

    public async Task<IActionResult> yourAsyncAction()
    {
        // access ctx here
    }
}

【讨论】:

  • 我认为这并不能真正回答问题。在控制责任倒置之后,还注入了上下文以协助单元测试
  • IMO - 提问者正在构建第二个服务,这可能会导致上述错误
猜你喜欢
  • 2015-06-25
  • 1970-01-01
  • 1970-01-01
  • 2022-07-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-11-28
  • 2017-02-27
相关资源
最近更新 更多