在C#中使用长进程发出调用数据库触发器

时间:2013-11-11 11:51:51

标签: c# sql sql-server triggers

我想读取一个巨大的目录及其子目录和文件,然后写入数据库。一切都很好,但我在一个表上放置一个触发器,当插入数据时它被触发并更新另一个表。触发器工作正常单个sql命令,但

由于主程序中的进程很长,因此不会触发触发器。我正在使用队列dequeue和backroundworker线程。(c#)

如何解决这个问题。任何想法都可以解决。

1 个答案:

答案 0 :(得分:0)

我认为触发器工作正常,但您需要在看到触发器效果之前处理所有数据。因此,我建议您将数据拆分为较小的部分(批处理),然后逐个将它们插入数据库。基本上,选择最适合您的设置的批量大小,并在迭代时加载数据。

以下是一些C#代码示例:

public void ProcessData(String rootDirectory, int batchSize) 
{
    IEnumerable<string> pathsToProcess = GetPathsToProcess(rootDirectory);

    int currentBatch = 0;
    while (currentBatch*batchSize < pathsToProcess.Length) 
    {
        // take a subset of the paths to process
        IEnumerable<string> batch = pathsToProcess
            .Skip(currentBatch*batchSize)
            .Take(batchSize);

        DoYourDatabaseLogic(batch);

        currentBatch++;
    }
}

上面的代码将对较小的数据子集执行数据库操作,之后您的触发器将针对该数据执行。这将发生在每个批次中。您仍然需要等待所有批次完成,但您可以看到已完成的批次的更改。

然而,使用这种方法需要担心一个重要问题:如果某些批次由于某种原因失败会发生什么?

  • 如果您必须还原整个pathsToProcess集合的所有更改(如果其中一个批次/子集失败),则应组织上述代码以在单个数据库事务中运行 ,并确保适当地进行回滚。
  • 如果pathsToProcess集合不需要完全回滚,我仍然建议在每个批次上使用事务。在这种情况下,您可能需要知道上次成功写入哪个批次,以便在再次处理数据时从中恢复。