VS 中的 SQL Server 数据库项目构建过程中 sql 脚本生成步骤的顺序

问题描述

我的解决方案中有一个 sql Sever 数据库项目和几个依赖项项目。

当我编译(在 VS 中)这个数据库项目时,我得到了一个 sql 脚本和一个 .dacpac 文件

但我也想将所有依赖项项目聚合到一个 dll 中,并仅为该结果 dll 创建 sql 脚本/.dacpac 文件

我正在使用 ILMerge.MSBuild.Tasks.ILMerge 在 sqlproj 中的 AfterBuild 事件上聚合所有 dll。但是这种聚合发生在生成 sql 脚本之后。

最后如何强制生成 sql 脚本?

构建日志:

2>------ Rebuild All started: Project: TestCLR,Configuration: Debug Any cpu ------
2>      D:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Current\Bin\Roslyn\csc.exe /noconfig /Nowarn:1701,1702,2008 /fullpaths /nostdlib+ /errorreport:prompt /warn:4 /define:DEBUG;TRACE /errorendlocation /preferreduilang:en-US /highentropyva+ /reference:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.8\mscorlib.dll" /reference:D:\Work\FF\sql-Objects\Tools\TestCLR\bin\Debug\TestLogic.dll /reference:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.8\System.Data.dll" /reference:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.8\System.dll" /reference:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.8\System.Xml.dll" /debug+ /debug:full /optimize- /out:obj\Debug\TestCLR.dll /subsystemversion:6.00 /target:library /warnaserror- /utf8output /langversion:7.3 TestProcedures.cs 
2>      Loading project references...
2>      Loading project files...
2>      Building the project model and resolving object interdependencies...
2>      Validating the project model...
2>      Writing model to D:\Work\FF\sql-Objects\Tools\TestCLR\obj\Debug\Model.xml...
2>      Writing create script to TestCLR_Create.sql...
2>      TestCLR -> D:\Work\FF\sql-Objects\Tools\TestCLR\bin\Debug\TestCLR.dll
2>      TestCLR -> D:\Work\FF\sql-Objects\Tools\TestCLR\bin\Debug\TestCLR.dacpac
2>      ILMerge bin\Debug\TestCLR.dll;bin\Debug\TestLogic.dll;bin\Debug\Sider.dll -> D:\Work\FF\sql-Objects\Tools\TestCLR\bin\Debug\TestCLR.dll
========== Rebuild All: 2 succeeded,0 Failed,0 skipped ==========

.sqlproj 部分与 ILMerge(现在它在最后一个位置。就在 /Project 标签之前)

  <UsingTask TaskName="ILMerge.MSBuild.Tasks.ILMerge" AssemblyFile="$(SolutionDir)\packages\ILMerge.MSBuild.Tasks.1.0.0.3\tools\ILMerge.MSBuild.Tasks.dll" />
  <Target Name="AfterBuild">
    <ItemGroup>
      <MergeAsm Include="bin\Debug\*.dll" />
    </ItemGroup>
    <PropertyGroup>
      <MergedAssembly>$(ProjectDir)$(OutDir)RedisCLR.dll</MergedAssembly>
    </PropertyGroup>
    <Message Text="ILMerge @(MergeAsm) -&gt; $(MergedAssembly)" Importance="high" />
    <ILMerge InputAssemblies="@(MergeAsm)" OutputFile="$(MergedAssembly)" TargetKind="SameAsPrimaryAssembly" />
  </Target>

非常感谢 Solomon Rutzky 先生。这个解决方案很有帮助。

<PropertyGroup>
  <sqlBuildDependsOn>
    BeforesqlBuild;
    $(sqlBuildDependsOn);
  </sqlBuildDependsOn>
</PropertyGroup>
<Target Name="BeforesqlBuild">
  ILMerge things
</Target>

但是有一件奇怪的事情。 Dll 在流程结束时来到 Bin\debug (我认为在 PostBuildEvent 步骤或附近)。如果我将 ILMerge 移到流程的上层 - 它会返回错误,即没有 DLL。将 obj 文件夹和依赖项目中的配置更改为 gater dll。

解决方法

有趣的问题。我不知道有什么简单方法可以做到这一点,或者一开始是否有可能。但是,我知道有两个选项可以改变构建过程:

选项 1

注入构建步骤/目标。 SSDT 缺少至少两个构建步骤/目标——“BeforeSqlBuild”和“BeforePublish”——因为“AfterBuild”目标在过程中为时已晚(如您所见)。

为了解决 SQL Server 2017 中引入的“CLR 严格安全性”问题(记录在我的以下帖子中:SQLCLR vs. SQL Server 2017,Part 3: “CLR strict security” – Solution 2),我更新了 .sqlproj 文件,将紧跟在结束 </Project> 标记之前(使用证书签署程序集):

<PropertyGroup>
  <SqlBuildDependsOn>
    BeforeSqlBuild;
    $(SqlBuildDependsOn);
  </SqlBuildDependsOn>
</PropertyGroup>
<Target Name="BeforeSqlBuild">
  <Exec Command="{DOS / Windows commands}"/>
</Target>

您可以保留 <Exec Command="..."/> 和/或添加现有“AfterBuild”目标的内容。但是,即使在正确的时间执行操作,我也不能完全确定您是否能够更改它想要序列化并放入“创建”脚本的程序集名称(即从使用“TestCLR .dll”到“RedisCLR.dll”)。您可以尝试重新分配构建变量,但我从未尝试过并且不确定是否允许。在这种情况下,下一个选项可能会有所帮助。

(请投票支持我的改进请求以改进 SSDT 构建过程:
Add MSBuild predefined Targets for "BeforeSqlBuild" and "BeforePublish" to SSDT SQL Server Database Projects)

选项 2

使用 .NET 创建可以访问对象、文件和整个过程的自定义构建任务: