SQL VS 中的服务器数据库项目。构建过程中 sql 脚本生成步骤的顺序
SQL Server database project in VS. Order of sql script generation step in build process
我的解决方案中有一个 SQL 服务器数据库项目和几个依赖项项目。
当我(在 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 Studio19\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) -> $(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 移到流程的上层 - 它 returns 错误,即没有 DLL。将配置从 obj 文件夹和从属项目更改为 gater dll。
有趣的问题。我不知道有什么 easy 方法可以做到这一点,或者一开始是否有可能。但是,我知道有两个选项可以改变构建过程:
选项 1
注入构建步骤/目标。 SSDT 至少缺少两个构建 steps/targets — “BeforeSqlBuild” 和 “BeforePublish” — 因为“AfterBuild”目标在过程中为时已晚(如您所见)。
为了绕过 SQL Server 2017 中引入的“CLR 严格安全”崩溃(记录在我的以下 post 中: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="..."/>
and/or 添加现有“AfterBuild”目标的内容。但是,即使在正确的时间执行此操作,我也不完全确定您是否能够更改它想要序列化的程序集名称并将其放入“创建”脚本(即从使用“TestCLR.dll”到“RedisCLR.dll”)。您可以尝试重新分配构建变量,但我从未尝试过并且不确定是否允许这样做。在这种情况下,下一个选项可能会有所帮助。
(请投票支持我改进 SSDT 构建过程的增强请求:
Add MSBuild predefined Targets for "BeforeSqlBuild" and "BeforePublish" to SSDT SQL Server Database Projects)
选项 2
使用 .NET 创建可以访问对象、文件和整个过程的自定义构建任务:
我的解决方案中有一个 SQL 服务器数据库项目和几个依赖项项目。
当我(在 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 Studio19\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) -> $(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 移到流程的上层 - 它 returns 错误,即没有 DLL。将配置从 obj 文件夹和从属项目更改为 gater dll。
有趣的问题。我不知道有什么 easy 方法可以做到这一点,或者一开始是否有可能。但是,我知道有两个选项可以改变构建过程:
选项 1
注入构建步骤/目标。 SSDT 至少缺少两个构建 steps/targets — “BeforeSqlBuild” 和 “BeforePublish” — 因为“AfterBuild”目标在过程中为时已晚(如您所见)。
为了绕过 SQL Server 2017 中引入的“CLR 严格安全”崩溃(记录在我的以下 post 中: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="..."/>
and/or 添加现有“AfterBuild”目标的内容。但是,即使在正确的时间执行此操作,我也不完全确定您是否能够更改它想要序列化的程序集名称并将其放入“创建”脚本(即从使用“TestCLR.dll”到“RedisCLR.dll”)。您可以尝试重新分配构建变量,但我从未尝试过并且不确定是否允许这样做。在这种情况下,下一个选项可能会有所帮助。
(请投票支持我改进 SSDT 构建过程的增强请求:
Add MSBuild predefined Targets for "BeforeSqlBuild" and "BeforePublish" to SSDT SQL Server Database Projects)
选项 2
使用 .NET 创建可以访问对象、文件和整个过程的自定义构建任务: