c# - Entity Framework 核心 : A second operation started on this context before a previous operation completed

标签 c# entity-framework asp.net-web-api

我正在使用 Entity Framework Core 开发 ASP.Net Core 2.0 项目

<PackageReference Include="Microsoft.EntityFrameworkCore" Version="2.0.1" />
  <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="2.0.0" PrivateAssets="All" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="2.0.0"/>

在我的列表方法之一中出现了这个错误:

InvalidOperationException: A second operation started on this context before a previous operation completed. Any instance members are not guaranteed to be thread safe.
Microsoft.EntityFrameworkCore.Internal.ConcurrencyDetector.EnterCriticalSection()

这是我的方法:

    [HttpGet("{currentPage}/{pageSize}/")]
    [HttpGet("{currentPage}/{pageSize}/{search}")]
    public ListResponseVM<ClientVM> GetClients([FromRoute] int currentPage, int pageSize, string search)
    {
        var resp = new ListResponseVM<ClientVM>();
        var items = _context.Clients
            .Include(i => i.Contacts)
            .Include(i => i.Addresses)
            .Include("ClientObjectives.Objective")
            .Include(i => i.Urls)
            .Include(i => i.Users)
            .Where(p => string.IsNullOrEmpty(search) || p.CompanyName.Contains(search))
            .OrderBy(p => p.CompanyName)
            .ToPagedList(pageSize, currentPage);

        resp.NumberOfPages = items.TotalPage;

        foreach (var item in items)
        {
            var client = _mapper.Map<ClientVM>(item);

            client.Addresses = new List<AddressVM>();
            foreach (var addr in item.Addresses)
            {
                var address = _mapper.Map<AddressVM>(addr);
                address.CountryCode = addr.CountryId;
                client.Addresses.Add(address);
            }

            client.Contacts = item.Contacts.Select(p => _mapper.Map<ContactVM>(p)).ToList();
            client.Urls = item.Urls.Select(p => _mapper.Map<ClientUrlVM>(p)).ToList();
            client.Objectives = item.Objectives.Select(p => _mapper.Map<ObjectiveVM>(p)).ToList();
            resp.Items.Add(client);
        }

        return resp;
    }

我有点迷茫,尤其是因为当我在本地运行它时它可以工作,但是当我部署到我的暂存服务器 (IIS 8.5) 时它会给我这个错误并且它工作正常。在我增加其中一个模型的最大长度后,错误开始出现。我还更新了相应 View 模型的最大长度。还有许多其他非常相似的列表方法,它们正在发挥作用。

我有一个 Hangfire 作业在运行,但这个作业不使用相同的实体。这就是我认为相关的所有内容。有什么可能导致这种情况的想法吗?

最佳答案

我不确定您是否正在使用 IoC 和依赖注入(inject)来解析您的 DbContext 可能被使用的地方。如果您这样做并且您正在使用来自 .NET Core(或任何其他 IoC 容器)的 native IoC 并且您收到此错误,请确保将您的 DbContext 注册为 Transient。做

services.AddDbContext<MyContext>(ServiceLifetime.Transient);

services.AddTransient<MyContext>();

代替

services.AddDbContext<MyContext>();

AddDbContext 将上下文添加为作用域,这在使用多线程时可能会导致问题。

还有 async / await operations使用异步 lambda 表达式时可能会导致此行为。

将其添加为 transient 也有其缺点。您将无法通过使用上下文的多个类对某些实体进行更改,因为每个类都将获得自己的 DbContext 实例。

对此的简单解释是,DbContext 实现不是线程安全的。您可以阅读更多相关信息 here

关于c# - Entity Framework 核心 : A second operation started on this context before a previous operation completed,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48767910/

相关文章:

c# - 构建流程模板出错

javascript - Angular 提示缺少一个根本没有声明的模块我

sql-server - 如何在 Entity Framework 数据库迁移中创建全文目录?

c# - 人们如何在 Web API 中测试他们的 [RequireHttps] 属性?

c# - 如何通过单击操作按钮在 gridview 中设置填充复选框被选中(真)

c# - C# 中的空格

.net - 自创建数据库以来,支持 'ApplicationDbContext' 上下文的模型已更改

linq - 如何在针对 Entity Framework 的 LINQ 查询中执行 "join"

asp.net-web-api - 在 WebAPI Formatter 中,如何从 HttpContent 获取 URL?

c# - 编码电子邮件以传递给 Web.API