Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Visual Studio SSDT Database project (.sqlproj) build - generate .dacpac using CLI without MSBUILD (msbuild.exe)

Looks as though dotnet CLI has no support for Database projects (.sqlproj) according to this: https://github.com/dotnet/sdk/issues/8546

in my case dotnet build fails with the following error:

C:...*.Database.sqlproj(59,3): error MSB4019: The imported project "C:\Program Files\dotnet\sdk\3.1.301\Microsoft\VisualStudio\v11.0\SSDT\Microsoft.Data.Tools.Schema.SqlTasks.targets" was not found. Confirm that the expression in the Import declaration "C:\Program Files\dotnet\sdk\3.1.301\Microsoft\VisualStudio\v11.0\SSDT\Microsoft.Data.Tools.Schema.SqlTasks.targets" is correct, and that the file exists on disk.

Needless to say, the solution compiles and generates .dacpac via Build in Visual Studio. I need this to work from command line. Do I have any solutions other than msbuild.exe? Perhaps some lovely nuget package out there that could help?

like image 674
Ruslan Avatar asked Apr 01 '26 04:04

Ruslan


1 Answers

I have managed to make it work as described in this article: https://erikej.github.io/efcore/2020/05/11/ssdt-dacpac-netcore.html

It requires a special type of .NET Standard Visual Studio project - MSBuild.Sdk.SqlProj (nuget download), which copies scripts from the Database project when compiled.

here's my build_database.cmd code:

SET db_project=Database.Build
dotnet tool install -g dotnet-script  
cd %db_project%
dotnet build
dotnet-script Program.csx 

And a C# script (Program.csx), which creates and deploys a .dacpac using Microsoft.SqlServer.DACFx nuget package:

#r "nuget: Microsoft.SqlServer.DACFx, 150.4769.1"
using Microsoft.SqlServer.Dac;

var dbName = "SampleDatabase";
var connectionString = $"Data Source=.;Initial Catalog={dbName};Integrated Security=True;";
var dacpacLocation = Directory.GetFiles(@".\bin", "Database.Build.dacpac", 
                                                           SearchOption.AllDirectories)[0];
var dbPackage = DacPackage.Load(dacpacLocation);
var services = new DacServices(connectionString);

services.Deploy(dbPackage, dbName, true); 

this approach is fully automated and can be used in either CI or local dev environment and, apparently, is also cross-platform (albeit I've only tested on Windows). Hope this helps :)

like image 160
Ruslan Avatar answered Apr 03 '26 17:04

Ruslan



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!