# SQL Database Projects integration

<Badge text="⭐ Community Toolkit" variant="tip" size="large" />

<Image
  src={sqlIcon}
  alt="SQL Database Projects icon"
  width={100}
  height={100}
  class:list={'float-inline-left icon'}
  data-zoom-off
/>

The Aspire SQL Database Projects hosting integration enables you to deploy SQL database schemas from SQL projects or DACPAC files during local development and testing. This integration supports both [MSBuild.Sdk.SqlProj](https://github.com/rr-wfm/MSBuild.Sdk.SqlProj) and [Microsoft.Build.Sql](https://www.nuget.org/packages/Microsoft.Build.Sql) project formats.

## Hosting integration

To get started with the Aspire SQL Database Projects hosting integration, install the [CommunityToolkit.Aspire.Hosting.SqlDatabaseProjects](https://www.nuget.org/packages/CommunityToolkit.Aspire.Hosting.SqlDatabaseProjects) NuGet package in the app host project.

<InstallPackage packageName="CommunityToolkit.Aspire.Hosting.SqlDatabaseProjects" />

```bash title="Terminal"
aspire add CommunityToolkit.Aspire.Hosting.SqlDatabaseProjects
```

This updates your `aspire.config.json` with the SQL Database Projects hosting integration package:

```json title="aspire.config.json" ins={3}
{
  "packages": {
    "CommunityToolkit.Aspire.Hosting.SqlDatabaseProjects": "*"
  }
}
```

The TypeScript AppHost bindings for SQL Database Projects are provided by the Community Toolkit package. After installation, the `.aspire/modules/aspire.mjs` file in your project includes `addSqlProject` and related APIs.

### Add SQL project

To deploy a SQL project to a SQL Server database, use the `AddSqlProject` extension method:

```csharp title="C# — AppHost.cs"
var builder = DistributedApplication.CreateBuilder(args);

var sql = builder.AddSqlServer("sql")
                 .AddDatabase("sqldb");

builder.AddSqlProject<Projects.DatabaseProject>("database-project")
       .WithReference(sql);

builder.AddProject<Projects.ExampleProject>()
       .WithReference(sql);

// After adding all resources, run the app...
```

This method takes a project reference to your SQL database project and deploys it to the specified database when the app host starts.
**Note:** Your SQL database project must use either [MSBuild.Sdk.SqlProj](https://github.com/rr-wfm/MSBuild.Sdk.SqlProj) or [Microsoft.Build.Sql](https://www.nuget.org/packages/Microsoft.Build.Sql) SDK. Add one of these to your SQL project file:

```xml
  <Project Sdk="MSBuild.Sdk.SqlProj/3.3.0">
  <!-- or -->
  <Project Sdk="Microsoft.Build.Sql/2.0.0">
```
```typescript title="TypeScript — apphost.mts"
import { createBuilder } from "./.aspire/modules/aspire.mjs";

const builder = await createBuilder();

const sql = await builder.addSqlServer("sql");
const sqldb = await sql.addDatabase("sqldb");

const databaseProject = await builder.addSqlProject("database-project");
await databaseProject.withReference(sqldb);

const exampleProject = await builder.addProject(
    "example-project",
    "../ExampleProject/ExampleProject.csproj");
await exampleProject.withReference(sqldb);

// After adding all resources, run the app...
```

### Add SQL package (NuGet)

To deploy a SQL database schema from a NuGet package, use the `AddSqlPackage` extension method:

```csharp title="C# — AppHost.cs"
var builder = DistributedApplication.CreateBuilder(args);

var sql = builder.AddSqlServer("sql")
                 .AddDatabase("sqldb");

builder.AddSqlPackage("Contoso.DatabasePackage", "1.0.0")
       .WithReference(sql);

builder.AddProject<Projects.ExampleProject>()
       .WithReference(sql);

// After adding all resources, run the app...
```

This method downloads the specified NuGet package and deploys the DACPAC it contains to the database.
**Tip:** When using NuGet packages, mark them with the `IsAspirePackageResource` metadata to indicate they're only used for Aspire deployment:

```xml
<PackageReference Include="Contoso.DatabasePackage" Version="1.0.0">
  <IsAspirePackageResource>true</IsAspirePackageResource>
</PackageReference>
```
**Note:** The current TypeScript AppHost bindings for this integration don't expose an `addSqlPackage` API. Use the C# AppHost to deploy a SQL database schema directly from a NuGet package.

### Add DACPAC file

To deploy a DACPAC file directly, use the `WithDacpac` extension method:

```csharp title="C# — AppHost.cs"
var builder = DistributedApplication.CreateBuilder(args);

var sql = builder.AddSqlServer("sql")
                 .AddDatabase("sqldb");

sql.WithDacpac("path/to/database.dacpac");

builder.AddProject<Projects.ExampleProject>()
       .WithReference(sql);

// After adding all resources, run the app...
```
```typescript title="TypeScript — apphost.mts"
import { createBuilder } from "./.aspire/modules/aspire.mjs";

const builder = await createBuilder();

const sql = await builder.addSqlServer("sql");
const sqldb = await sql.addDatabase("sqldb");

const databaseProject = await builder.addSqlProject("database-project");
await databaseProject.withDacpac("path/to/database.dacpac");
await databaseProject.withReference(sqldb);

const exampleProject = await builder.addProject(
    "example-project",
    "../ExampleProject/ExampleProject.csproj");
await exampleProject.withReference(sqldb);

// After adding all resources, run the app...
```

### Configure DAC deployment options

You can customize the DACPAC deployment behavior using the `WithConfigureDacDeployOptions` method:

```csharp title="C# — AppHost.cs"
var builder = DistributedApplication.CreateBuilder(args);

var sql = builder.AddSqlServer("sql")
                 .AddDatabase("sqldb");

sql.AddSqlProject<Projects.DatabaseProject>("database-project")
   .WithConfigureDacDeployOptions(options =>
   {
       options.BlockOnPossibleDataLoss = false;
       options.DropObjectsNotInSource = true;
   });

// After adding all resources, run the app...
```
```typescript title="TypeScript — apphost.mts"
import { createBuilder } from "./.aspire/modules/aspire.mjs";

const builder = await createBuilder();

const sql = await builder.addSqlServer("sql");
const sqldb = await sql.addDatabase("sqldb");

const databaseProject = await builder.addSqlProject("database-project");
await databaseProject.withReference(sqldb);
await databaseProject.withDacDeployOptions("path/to/database.publish.xml");

// After adding all resources, run the app...
```
**Note:** The current TypeScript AppHost bindings expose `withDacDeployOptions` for publish profile paths, but don't expose the `WithConfigureDacDeployOptions` callback API. Use the C# AppHost when you need to configure DAC deployment options inline.

### Redeploy action

The SQL Database Projects integration adds a custom "Redeploy" action to the Aspire dashboard. This action allows you to manually trigger a redeployment of the database schema without restarting the entire app host.

To use the Redeploy action:
1. Open the Aspire dashboard
2. Find your SQL database resource
3. Click the "Redeploy" action in the resource's menu

This is useful during development when you make changes to your database schema and want to quickly apply them.

### Multiple SQL projects

You can add multiple SQL projects to the same database or different databases:

```csharp title="C# — AppHost.cs"
var builder = DistributedApplication.CreateBuilder(args);

var sql = builder.AddSqlServer("sql");

var db1 = sql.AddDatabase("db1");
db1.AddSqlProject<Projects.Database1Project>("db1-project");

var db2 = sql.AddDatabase("db2");
db2.AddSqlProject<Projects.Database2Project>("db2-project");

// After adding all resources, run the app...
```
```typescript title="TypeScript — apphost.mts"
import { createBuilder } from "./.aspire/modules/aspire.mjs";

const builder = await createBuilder();

const sql = await builder.addSqlServer("sql");

const db1 = await sql.addDatabase("db1");
const db1Project = await builder.addSqlProject("db1-project");
await db1Project.withReference(db1);

const db2 = await sql.addDatabase("db2");
const db2Project = await builder.addSqlProject("db2-project");
await db2Project.withReference(db2);

// After adding all resources, run the app...
```

### Ability to skip deployment

You can use the `WithSkipWhenDeployed` method to avoid re-deploying your SQL Database Project if no changes have been made. This is useful in scenarios where the SQL container database is persisted to permanent storage and will significantly reduce the app host startup time.

```csharp title="C# — AppHost.cs"
var builder = DistributedApplication.CreateBuilder(args);

var sql = builder.AddSqlServer("sql")
    .WithDataVolume("data")
    .WithLifetime(ContainerLifetime.Persistent);

var db1 = sql.AddDatabase("db1");

db1.AddSqlProject<Projects.Database1Project>("db1-project")
   .WithSkipWhenDeployed();

// After adding all resources, run the app...
```
```typescript title="TypeScript — apphost.mts"
import { createBuilder } from "./.aspire/modules/aspire.mjs";

const builder = await createBuilder();

const sql = await builder.addSqlServer("sql");
await sql.withDataVolume("data");
await sql.withLifetime("Persistent");

const db1 = await sql.addDatabase("db1");

const db1Project = await builder.addSqlProject("db1-project");
await db1Project.withReference(db1);
await db1Project.withSkipWhenDeployed();

// After adding all resources, run the app...
```

## See also

- [MSBuild.Sdk.SqlProj](https://github.com/rr-wfm/MSBuild.Sdk.SqlProj)
- [Microsoft.Build.Sql](https://www.nuget.org/packages/Microsoft.Build.Sql)
- [SQL Server Data Tools (SSDT)](https://learn.microsoft.com/sql/ssdt/sql-server-data-tools)
- [Aspire Community Toolkit](https://github.com/CommunityToolkit/Aspire)
- [Aspire integrations overview](/integrations/overview/)
- [Aspire GitHub repo](https://github.com/microsoft/aspire)