使用SMO从并行循环中的.net中的SQL服务器数据库编写对象定义

Aja*_*ayK 6 .net c# sql smo task-parallel-library

我正在使用SMO使用.Net代码从Sql server数据库编写我的对象.但截至目前,我正在经历一个顺序循环.

foreach(var table in TableCollection)
{
 var stringCollection=table.Script();
}
Run Code Online (Sandbox Code Playgroud)

它工作正常.但是当我将相同的循环转换为Parallel.ForEach循环时:

Parallel.ForEach(TableCollection,table=>
{
 var stringCollection=table.Script();
});
Run Code Online (Sandbox Code Playgroud)

它无法编写脚本.是否有人使用相同的方法或任何其他方法并行编写Sql server中的对象?

更新:

到目前为止我还没有能够解决Parallel LOOP问题,但我使用了下面提到的代码:

 server.SetDefaultInitFields(true);                
Run Code Online (Sandbox Code Playgroud)

它在一定程度上提高了性能.

svi*_*ick 4

看来 SMO 并不是以线程安全的方式构建的。当您调用Script()a时Table,它会使用其中的某些共享状态Server,因此您无法在同一个表中的两个表上执行它ServerServer但是您可以通过为每个创建新对象来解决这个问题Table

\n\n
private static TableCollection GetTables()\n{\n    Server server = new Server(\xe2\x80\xa6);\n    Database database = server.Databases[\xe2\x80\xa6];\n    var tables = database.Tables;\n    return tables;\n}\n\n\xe2\x80\xa6\n\nParallel.For(0, GetTables().Count,\n    i =>\n    {\n        var stringCollection = GetTables()[i].Script();\n        \xe2\x80\xa6\n    });\n
Run Code Online (Sandbox Code Playgroud)\n\n

这将使您的查询并行,但我不知道它是否会让它们实际上更快。

\n\n

编辑:如果您想为每个线程创建一个,您可以使用允许线程局部初始化Server的重载。Parallel.For()就像是:

\n\n
Parallel.For(0, GetTables().Count,\n    () => GetTables(),\n    (i, _, tables) =>\n    {\n        var stringCollection = tables[i].Script();\n        \xe2\x80\xa6\n        return tables;\n    },\n    tables => { });\n
Run Code Online (Sandbox Code Playgroud)\n\n

这样,每个线程都会有自己的Server对象,但只有一个。

\n