LinqToSql - 并行 - DataContext和Parallel

时间:2010-05-05 19:25:23

标签: linq-to-sql .net-4.0 parallel-processing datacontext

在.NET 4和多核环境中,如果我们使用DataLoadOptions.LoadWith,linq to sql datacontext对象是否会利用新的并行?

修改

我知道linq to sql没有并行化普通查询。我想知道的是,当我们指定DataLoadOption.LoadWith时,它是否使用并行化来执行每个实体及其子实体之间的匹配?

示例:

using(MyDataContext context = new MyDataContext())
{
     DataLaodOptions options =new DataLoadOptions();
     options.LoadWith<Product>(p=>p.Category);
     return this.DataContext.Products.Where(p=>p.SomeCondition);
}

生成以下sql:

Select Id,Name from Categories
Select Id,Name, CategoryId from Products where p.SomeCondition

创建所有产品后,我们会有

categories.ToArray();
Parallel.Foreach(products, p =>
{
    p.Category == categories.FirstOrDefault(c => c.Id == p.CategoryId);
});

categories.ToArray();
foreach(Product product in products)
{
    product.Category = categories.FirstOrDefault(c => c.Id == product.CategoryId);
}

1 个答案:

答案 0 :(得分:12)

不,LINQ to SQL没有。在.NET方面几乎无法并行化。所有LINQ to SQL都将表达式树转换为SQL查询。 SQL Server将执行这些SQL语句,并且能够并行执行此操作。

不要忘记,虽然您可以使用LINQ to SQL LINQ查询执行类似的操作,但这不是一个好主意:

// BAD CODE!!! Don't parallelize a LINQ to SQL query
var q =
    from customer in db.Customers.AsParallel()
    where customer.Id == 5
    select customer;

虽然这会产生正确的结果,但您无法获得希望的性能提升。 PLINQ无法处理IQueryable个对象。因此,它只会将IQueryable作为IEnumerable处理(因此迭代它)。它将并行处理db.Customers集合并使用多个线程来过滤客户。虽然听起来不错,但这意味着它将从数据库中检索完整的客户集合!如果没有AsParallel构造,LINQ to SQL将能够通过将WHERE id = @ID添加到SQL来优化此查询。 SQL Server将能够使用索引(可能还有多线程)来获取值。

虽然LINQ to SQL引擎在将实体与其子实体匹配时有一些优化空间,但目前框架中似乎没有这样的优化(或者至少,我无法找到任何使用Reflector)。