使用c#提高dacpac部署的性能

jru*_*ren 8 c# sql-server localdb dacpac sql-server-data-tools

我们正在部署到MS SQL Server localdb集成测试。

我们构建了一个数据库项目,并将生成的dacpac文件复制以供 IntegrationTests 项目使用。到目前为止,我们有:

DatabaseProject.sqlproj
    bin/debug/DatabaseProject.dacpac
IntegrationTests.csproj 
    bin/debug/DatabaseProject.dacpac
Run Code Online (Sandbox Code Playgroud)

我们在 IntegrationTests 项目中有一个程序集设置,其中创建了一个新的新数据库并将其dacpac部署到localdb. 在 TearDown 中,数据库被删除,因此我们有一个确定性的测试状态。

这是部署 的代码dacpac,它使用DacServices( Microsoft.SqlServer.Dac, System.Data.SqlLocalDb, System.Data.SqlClient):

public void CreateAndInitializeFromDacpac(
ISqlLocalDbInstance localDbInstance,
string databaseName,
string connectionString,
string dacpacPath)
{

    using (var cx = localDbInstance.CreateConnection())
    {
        cx.Open();
        using (var command = new SqlCommand(
            string.Format("CREATE DATABASE {0}", databaseName), cx))
            command.ExecuteNonQuery();
    }

    var svc = new DacServices(connectionString);

    svc.Deploy(
        DacPackage.Load(dacpacPath),
        databaseName,
        true
        );
}
Run Code Online (Sandbox Code Playgroud)

我们现在有几个数据库项目,部署每个项目大约需要8 秒。这会增加执行测试的总时间。

是否有可能以某种方式提高dacpac.

Ed *_*ott 7

加文说得对!

不要拆除数据库,而是使用“创建新数据库”选项,这样SSDT在知道一个模型为空时就不必浪费时间比较两个模型。

部署代码应改为:

var dacOptions = new DacDeployOptions { 
               CreateNewDatabase = true
            };

svc.Deploy(
    DacPackage.Load(dacpacPath),
    databaseName,
    true, 
    options: dacOptions
    );
Run Code Online (Sandbox Code Playgroud)

SSDT如果你设置了这个标志,还有很多额外的优化可以做——如果你不方便使用反射器,看看Microsoft.Data.Tools.Schema.Sql.dllMicrosoft.Data.Tools.Schema.Sql.Deployment.SqlDeploymentPlanGenerator.OnInitialize(SqlDeployment)。如果设置了该标志,它会跳过整个连接到数据库和从部署T-SQL到模型的逆向工程。

这可能会导致一个潜在的错误,即人们更改模型数据库以包含一些对象,然后使用 SSDT 部署模型数据库中的对象,但随着边缘情况的发展,这听起来很低!

Parallel.Foreach正如 TheGameiswar 所建议的那样,通过使用 并行化代码,还可以提高多数据库情况的性能。

  • 小注意: DacPackage 对象是一次性的。我会建议处理它们。 (2认同)