【问题标题】:Parallel calls to dbcontext in .NET Core EF core在 .NET Core EF 核心中并行调用 dbcontext
【发布时间】:2020-05-20 02:46:27
【问题描述】:

项目用途:

  • SQL 服务器
  • .NET Core 3
  • EF 核心

在我的项目中,我有数百万条数据/记录,我需要在一个 API 中从 4 个不同的表中发出并行读取请求。 DBContext 有一个作用域生命周期,这是推荐的。我需要对DBContext 进行并行调用,但是当我尝试它时,它说第二个实例已经在一个实例已经在使用时启动(因为生命周期是有范围的)。

  • 我尝试对这些特定查询使用AsNoTracking(),但仍然出现同样的错误。
  • 我无法使用瞬态 Lifetime。
  • 项目使用存储库模式,不能在控制器中使用新的DBcontext 实例。

    public MemberRepository(
        IMemberEntityMappingHelper memberEntityMappingHelper,
        IMapperExtension mapper,
        ProjectDBContext context)
        : base(context, mapper)
    {
        _memberEntityMappingHelper = memberEntityMappingHelper;
    }
        public List<MemberSummaryModel> GetMembers(int foreignKeyId)
    {
        List<MemberEntity> members = _context.Members
                                                                        .Include(x => x.Sample)
                                                                        .Where(x =>
                                                                          x.SampleForeignkeyId == foreignKeyId
                                                                          && x.IsDeleted == false)
                                                                        .ToList();
    
        return _memberEntityMappingHelper.EntityToSummaryModelList(members);
    }
    

并行调用 -

Parallel.Invoke(() =>
{
// Read from table 1
}, 
() => 
{
// Read from table 2
});

我需要优化我的代码以缩短响应时间。

  1. 有什么方法可以运行并行查询(只读)?
  2. DbContext 不是线程安全的,一个实例无法更新/创建一个实例的条目,但为什么我不能进行并行读取查询?
  3. 预计一次获得 30,000 行需要多长时间(当我使用所有索引时)?如何减少它,对我来说,加载数据需要 2 分钟?

【问题讨论】:

  • 如果您的 DbContext 实例是 Scoped 并且您没有在线程之间共享它们,您应该不会看到此错误。你能发布一个简化的重现来演示这个问题吗?
  • 我在发出并行读取请求时看到此错误,当时共享 dbcontext。
  • 您的连接字符串中是否启用了MultipleActiveResultSets
  • 我尝试了 MultipleActiveResultSets 启用仍然相同的错误 - 发生了一个或多个错误。 (在前一个操作完成之前在此上下文上启动了第二个操作。这通常是由使用相同 DbContext 实例的不同线程引起的

标签: sql-server multithreading asp.net-core task-parallel-library ef-core-3.0


【解决方案1】:

DbContext 不是线程安全的,一个实例无法更新/创建一个实例的条目, 但是为什么我不能进行并行读取查询?

因为 DbContext 不是 Tthread 安全的。时期。不是“更新/创建”——根本不是。大部分都失败了,最后一个 DbConnection 上没有并行 SQL 语句的假设,而 MARS 没有改变这一点 - 它允许重叠查询结果,而不是重叠查询执行。

预计一次获得 30,000 行的时间(当我使用所有 索引)?

索引:与对象的大小和您的网络连接无关。上次我 dd 说半秒内有 50 万个条目 - 但那些条目很小且网络连接非常快。

有什么方法可以运行并行查询(只读)?

是的,多个数据库连接,多个 DbContext。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-06-10
    • 2019-03-22
    • 2020-05-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-10
    相关资源
    最近更新 更多