繁体   English   中英

使用多个Entity Framework上下文并行查询

[英]Parallelization of queries using multiple Entity Framework contexts

考虑一下需要执行和合并数据库中几个隔离查询的结果的情况。 每个单独的查询均基于从其他位置提供的参数。

一种方法是依次执行这些查询并合并结果:

public IEnumerable<SomeEntity> GetSomeEntities(List<int> parameters)
{
    var entities = new List<SomeEntity>();

    using(var context = new MyContext())
    {
        entities = parameters.SelectMany(p=> SomeComplexQuery(p);
    }

    return entities;
}

上述解决方案的问题在于,性能现在与参数列表的大小成正比。 SomeComplexQuery相对耗费资源。

另一种解决方案是使用并行化:

public IEnumerable<SomeEntity> GetSomeEntities(List<int> parameters)
{
    var entities = new List<SomeEntity>();

    Parallel.ForEach(parameters, p => 
    {
        using(var context = new MyContext())
        {
            entities.AddRange(SomeComplexQuery(p)); // Assume thread-safety
        }
    };

    return entities;
}

当我运行上述解决方案时,可以获得更好的结果,但是我很担心:

  • 并行打开多个上下文会引起什么问题? 如果我们有一个大小为20甚至更大的参数列表怎么办? 系统负载会导致进一步的不良结果吗?

  • 专门针对SQL Azure,由于建立新的数据库连接时增加了延迟,这会被认为是一个坏主意吗?

我正在使用Entity Framework 6,Azure Web角色和SQL Azure。

可以运行多个线程,每个线程都有自己的上下文实例。 我自己在一个过程中执行此操作,该过程可能会引起相对较多的插入或更新,到目前为止没有任何问题。

.Net连接池是线程安全的:没有物理数据库连接会受到竞争条件的影响。 可以访问物理连接的.Net DbConnection对象不是线程安全的,但是每个上下文都管理自己的连接对象,因此它们不会被多个线程共享。 Sql Azure连接也被池化,但是您必须部署重试策略(与任何Sql Azure连接一样)。 EF6 支持连接弹性

请注意, List<T>不是线程安全的。 您最好对entities使用并发集合

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM