在Where语句

时间:2017-03-27 14:22:44

标签: c# sql-server linq-to-sql

我正在我的数据库中的一个表上做一个简单的foreach循环,但是,如果我在该循环内尝试对数据库进行任何其他查询,那么它似乎是数据库(或者可能只是我的DataContext )被锁定了。

我的表格是 Process 表(约44,000行)和子 ProcessValidation 表(约133,000行)。 ProcessValidation有一个valProcessKey,它指向Process并对其应用了索引。我的代码如下:

using (var dbContext = new BTR.Data.Legacy.DataContexts.xDS.DataContext(connectionString) { DeferredLoadingEnabled = false, ObjectTrackingEnabled = false })
{
    var dataLoadProcesses = 
        dbContext.Processes
                 .Where(p => new[] { "UpdateProcess", "RBLProcess", "RBLCalcProcess" }.Contains(p.procType));

    // All these count queries work outside of the foreach  
    Console.WriteLine(dataLoadProcesses.Count());
    Console.WriteLine(dbContext.ProcessValidations.Count());
    Console.WriteLine(dbContext.ProcessValidations.Count(v => v.valProcessKey == 1591));

    foreach (var process in dataLoadProcesses)
    {
        // can grab fields from 'process' object

        // can *NOT* execute any other queries against ProcessValidation
    }
}

在我的foreach内,我可以从每个进程行中获取字段,一切正常,但如果我再次尝试查询数据库,它会锁定。例如,像下面这样的简单计数查询永远不会返回并且只是锁定(我认为最终它实际上给了我一个OutOfMemoryException)。

var existingValidations = 
    dbContext.ProcessValidations.Count(v => v.valProcessKey == process.procKey);

我尝试在查询周围使用TransactionScope来有效地发出NOLOCK命令,但这也无济于事。

上面,我说可能只有DataContext被锁定了,因为当它被锁定时,我使用不同的DataContext在LINQPad脚本中对数据库执行了一个Count()查询,并立即返回(即使最初的DataContext仍然在旋转)

有人认为这可能与Processing large datasets using LINQ重复,但我认为不适用。

  1. 我在循环之外创建了我的上下文
  2. 它锁定了第一个Count()查询。
  3. 在我遇到问题之后,创建一个编译的查询可能有助于性能和内存消耗,但我还没有达到这一点

1 个答案:

答案 0 :(得分:0)

问题是LINQ正在获取LOCK。您可以使用foreach (var process in dataLoadProcesses.ToList())轻松避免它。在this回答你有一点解释。我认为不够,因为我不明白for-each如何阻止count,但这是一个开始。

如果您希望/需要查询根本不阻止数据库,我找到了this其他链接。

这两个解决方案必须在处理之前引入整个查询,并且可能有更好的解决方案。