[英]Parallelization of queries using multiple Entity Framework contexts
Consider the situation where I need to perform and combine the results of several isolated queries from the database. 考虑一下需要执行和合并数据库中几个隔离查询的结果的情况。 Each individual query is based on a parameter, which is supplied from elsewhere.
每个单独的查询均基于从其他位置提供的参数。
One way would be to perform these queries sequentially and union the results: 一种方法是依次执行这些查询并合并结果:
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;
}
The issue with the above solution is that performance is now proportional to the size of the parameter list. 上述解决方案的问题在于,性能现在与参数列表的大小成正比。
SomeComplexQuery
is relatively resource-intensive. SomeComplexQuery
相对耗费资源。
Another solution would be to use parallelization: 另一种解决方案是使用并行化:
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;
}
When I run the above solution, I get much better results, but I'm concerned: 当我运行上述解决方案时,可以获得更好的结果,但是我很担心:
What issues could arise from opening multiple contexts in parallel? 并行打开多个上下文会引起什么问题? What if we had a parameter list of size 20 or even more?
如果我们有一个大小为20甚至更大的参数列表怎么办? Could system load result in further undesirable results?
系统负载会导致进一步的不良结果吗?
Specifically for SQL Azure, would this be considered a bad idea due to the added latency when establishing new database connections? 专门针对SQL Azure,由于建立新的数据库连接时增加了延迟,这会被认为是一个坏主意吗?
I am using Entity Framework 6, Azure Web Roles and SQL Azure. 我正在使用Entity Framework 6,Azure Web角色和SQL Azure。
It's alright to run multiple threads, each having their own context instance. 可以运行多个线程,每个线程都有自己的上下文实例。 I'm doing this myself in a process that may give rise to relatively many inserts or updates, so far without any problems.
我自己在一个过程中执行此操作,该过程可能会引起相对较多的插入或更新,到目前为止没有任何问题。
The .Net connection pool is thread-safe: no physical database connection will suffer from race conditions. .Net连接池是线程安全的:没有物理数据库连接会受到竞争条件的影响。 The .Net
DbConnection
objects that give access to a physical connection are not thread-safe, but each context manages its own connection objects, so they won't be shared by multiple threads. 可以访问物理连接的.Net
DbConnection
对象不是线程安全的,但是每个上下文都管理自己的连接对象,因此它们不会被多个线程共享。 Sql Azure connections are also pooled, but you'll have to deploy retry strategies (as with any Sql Azure connection). Sql Azure连接也被池化,但是您必须部署重试策略(与任何Sql Azure连接一样)。 EF6 supports connection resiliency .
EF6 支持连接弹性 。
Note that List<T>
is not thread-safe. 请注意,
List<T>
不是线程安全的。 You better use a concurrent collection for entities
. 您最好对
entities
使用并发集合 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.