# Connect to SQL Server

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

This page describes how consuming apps connect to a SQL Server resource that's already modeled in your AppHost. For the AppHost API surface — adding a SQL Server instance, databases, data volumes, bind mounts, and more — see [SQL Server Hosting integration](../sql-server-host/).

When you reference a SQL Server resource from your AppHost, Aspire injects the connection information into the consuming app as environment variables. Your app can either read those environment variables directly — the pattern works the same from any language — or, in C#, use the Aspire SQL Server client integration for automatic dependency injection, health checks, and telemetry.

## Connection properties

Aspire exposes each property as an environment variable named `[RESOURCE]_[PROPERTY]`. For instance, the `Uri` property of a resource called `sqldb` becomes `SQLDB_URI`.

### SQL Server server resource

The SQL Server server resource exposes the following connection properties:

| Property Name          | Description |
| ---------------------- | ----------- |
| `Host`                 | The hostname or IP address of the SQL Server instance |
| `Port`                 | The port number the SQL Server instance is listening on |
| `Username`             | The username for authentication |
| `Password`             | The password for authentication |
| `Uri`                  | The connection URI in mssql:// format, with the format `mssql://{Username}:{Password}@{Host}:{Port}` |
| `JdbcConnectionString` | JDBC-format connection string, with the format `jdbc:sqlserver://{Host}:{Port};trustServerCertificate=true`. User and password credentials are provided as separate `Username` and `Password` properties. |

**Example connection strings:**

```
Uri: mssql://sa:p%40ssw0rd1@localhost:1433
JdbcConnectionString: jdbc:sqlserver://localhost:1433;trustServerCertificate=true
```

### SQL Server database resource

The SQL Server database resource inherits all properties from its parent server resource and adds:

| Property Name          | Description |
| ---------------------- | ----------- |
| `Uri`                  | The connection URI with the database name, with the format `mssql://{Username}:{Password}@{Host}:{Port}/{DatabaseName}` |
| `JdbcConnectionString` | JDBC connection string with the database name, with the format `jdbc:sqlserver://{Host}:{Port};trustServerCertificate=true;databaseName={DatabaseName}`. User and password credentials are provided as separate `Username` and `Password` properties. |
| `Database`             | The name of the database |

**Example connection strings:**

```
Uri: mssql://sa:p%40ssw0rd1@localhost:1433/catalog
JdbcConnectionString: jdbc:sqlserver://localhost:1433;trustServerCertificate=true;databaseName=catalog
```

## Connect from your app

Pick the language your consuming app is written in. Each example assumes your AppHost adds a SQL Server database resource named `sqldb` and references it from the consuming app.

For C# apps, the recommended approach is the Aspire SQL Server client integration. It registers a [`SqlConnection`](https://learn.microsoft.com/dotnet/api/microsoft.data.sqlclient.sqlconnection) through dependency injection and adds health checks and telemetry automatically. If you'd rather read environment variables directly, see the [Read environment variables](#read-environment-variables-in-c) section at the end of this tab.

#### Install the client integration

Install the [📦 Aspire.Microsoft.Data.SqlClient](https://www.nuget.org/packages/Aspire.Microsoft.Data.SqlClient) NuGet package in the client-consuming project:

<InstallDotNetPackage packageName="Aspire.Microsoft.Data.SqlClient" />

#### Add the SQL Server client

In _Program.cs_, call `AddSqlServerClient` on your `IHostApplicationBuilder` to register a `SqlConnection`:

```csharp title="C# — Program.cs"
builder.AddSqlServerClient(connectionName: "sqldb");
```
**Tip:** The `connectionName` must match the SQL Server database resource name from the AppHost. For more information, see [Add SQL Server resource](../sql-server-host/#add-sql-server-resource).

Resolve the connection through dependency injection:

```csharp title="C# — ExampleService.cs"
public class ExampleService(SqlConnection connection)
{
    // Use connection...
}
```

For more information on dependency injection, see [.NET dependency injection](https://learn.microsoft.com/dotnet/core/extensions/dependency-injection).

#### Add keyed SQL Server clients

To register multiple `SqlConnection` instances with different connection names, use `AddKeyedSqlServerClient`:

```csharp title="C# — Program.cs"
builder.AddKeyedSqlServerClient(name: "mainDb");
builder.AddKeyedSqlServerClient(name: "loggingDb");
```

Then resolve each instance by key:

```csharp title="C# — ExampleService.cs"
public class ExampleService(
    [FromKeyedServices("mainDb")] SqlConnection mainDbConnection,
    [FromKeyedServices("loggingDb")] SqlConnection loggingDbConnection)
{
    // Use connections...
}
```

For more information on keyed services, see [.NET dependency injection: Keyed services](https://learn.microsoft.com/dotnet/core/extensions/dependency-injection#keyed-services).

#### Configuration

The Aspire SQL Server client integration offers multiple ways to provide configuration.

**Connection strings.** When using a connection string from the `ConnectionStrings` configuration section, pass the connection name to `AddSqlServerClient`:

```csharp title="C# — Program.cs"
builder.AddSqlServerClient("sqldb");
```

The connection string is resolved from the `ConnectionStrings` section:

```json title="JSON — appsettings.json"
{
  "ConnectionStrings": {
    "sqldb": "Data Source=myserver;Initial Catalog=sqldb"
  }
}
```

For more information on connection string format, see [SqlConnection.ConnectionString](https://learn.microsoft.com/dotnet/api/system.data.sqlclient.sqlconnection.connectionstring#remarks).

**Configuration providers.** The client integration supports `Microsoft.Extensions.Configuration`. It loads `MicrosoftDataSqlClientSettings` from _appsettings.json_ (or any other configuration source) by using the `Aspire:Microsoft:Data:SqlClient` key:

```json title="JSON — appsettings.json"
{
  "Aspire": {
    "Microsoft": {
      "Data": {
        "SqlClient": {
          "ConnectionString": "Data Source=myserver;Initial Catalog=sqldb",
          "DisableHealthChecks": false,
          "DisableMetrics": false
        }
      }
    }
  }
}
```

For the complete SQL Server client integration JSON schema, see [Aspire.Microsoft.Data.SqlClient/ConfigurationSchema.json](https://github.com/microsoft/aspire/blob/main/src/Components/Aspire.Microsoft.Data.SqlClient/ConfigurationSchema.json).

**Inline delegates.** Pass an `Action<MicrosoftDataSqlClientSettings>` to configure settings inline, for example to disable health checks:

```csharp title="C# — Program.cs"
builder.AddSqlServerClient(
    "sqldb",
    static settings => settings.DisableHealthChecks = true);
```

#### Client integration health checks

Aspire client integrations enable health checks by default. The SQL Server client integration adds:

- A health check that attempts to connect to the SQL Server instance and execute a command.
- Integration with the `/health` HTTP endpoint, where all registered health checks must pass before the app is considered ready to accept traffic.

#### Observability and telemetry

The Aspire SQL Server client integration automatically configures logging, tracing, and metrics through OpenTelemetry.

**Logging:** The SQL Server client integration currently doesn't enable logging by default due to limitations of the `SqlClient`.

**Tracing** activities:

- `OpenTelemetry.Instrumentation.SqlClient`

**Metrics** from `Microsoft.Data.SqlClient.EventSource`:

- `active-hard-connections`
- `hard-connects`
- `hard-disconnects`
- `active-soft-connects`
- `soft-connects`
- `soft-disconnects`
- `number-of-non-pooled-connections`
- `number-of-pooled-connections`
- `number-of-active-connection-pool-groups`
- `number-of-inactive-connection-pool-groups`
- `number-of-active-connection-pools`
- `number-of-inactive-connection-pools`
- `number-of-active-connections`
- `number-of-free-connections`
- `number-of-stasis-connections`
- `number-of-reclaimed-connections`

Any of these telemetry features can be disabled through the configuration options above.

#### Read environment variables in C\#

If you prefer not to use the Aspire client integration, you can read the Aspire-injected connection URI from the environment and open a connection using [📦 Microsoft.Data.SqlClient](https://www.nuget.org/packages/Microsoft.Data.SqlClient/):

```csharp title="C# — Program.cs"
using Microsoft.Data.SqlClient;

var connectionString = Environment.GetEnvironmentVariable("SQLDB_URI");

await using var connection = new SqlConnection(connectionString);
await connection.OpenAsync();

// Use connection to query the database...
```

Use the [`microsoft/go-mssqldb`](https://github.com/microsoft/go-mssqldb) driver, Microsoft's officially maintained Go driver for SQL Server:

```bash title="Terminal"
go get github.com/microsoft/go-mssqldb
```

Read the injected environment variable and connect:

```go title="Go — main.go"
package main

import (
    "context"
    "database/sql"
    "os"

    _ "github.com/microsoft/go-mssqldb"
)

func main() {
    // Read the Aspire-injected connection URI
    connStr := os.Getenv("SQLDB_URI")

    db, err := sql.Open("mssql", connStr)
    if err != nil {
        panic(err)
    }
    defer db.Close()

    if err := db.PingContext(context.Background()); err != nil {
        panic(err)
    }
}
```

Install [`pyodbc`](https://github.com/mkleehammer/pyodbc) and the [Microsoft ODBC Driver 18 for SQL Server](https://learn.microsoft.com/sql/connect/odbc/download-odbc-driver-for-sql-server):

```bash title="Terminal"
pip install pyodbc
```
**Note:** You also need to install the ODBC driver separately. For platform-specific instructions, see [Microsoft ODBC Driver for SQL Server](https://learn.microsoft.com/sql/connect/odbc/download-odbc-driver-for-sql-server).

Read the injected environment variables and connect:

```python title="Python — app.py"
import os
import pyodbc

# Read Aspire-injected connection properties
sql_host = os.getenv("SQLDB_HOST")
sql_port = os.getenv("SQLDB_PORT", "1433")
sql_user = os.getenv("SQLDB_USERNAME")
sql_password = os.getenv("SQLDB_PASSWORD")
sql_database = os.getenv("SQLDB_DATABASE")

connection_string = (
    f"DRIVER={{ODBC Driver 18 for SQL Server}};"
    f"SERVER={sql_host},{sql_port};"
    f"DATABASE={sql_database};"
    f"UID={sql_user};"
    f"PWD={sql_password};"
)

conn = pyodbc.connect(connection_string)
cursor = conn.cursor()

# Use cursor to query the database...
```

Or use the connection URI directly:

```python title="Python — Connect with URI"
import os
import pyodbc

# Read the Aspire-injected connection URI
uri = os.getenv("SQLDB_URI")

# pyodbc requires an ODBC-style connection string — build it from the URI
# or use individual properties as shown above
```

Install the [`mssql`](https://github.com/tediousjs/node-mssql) npm package, the most popular SQL Server client for Node.js:

```bash title="Terminal"
npm install mssql
npm install --save-dev @types/mssql
```

Read the injected environment variables and connect:

```typescript title="TypeScript — index.ts"
import sql from 'mssql';

// Read Aspire-injected connection properties
const config: sql.config = {
    server: process.env.SQLDB_HOST!,
    port: Number(process.env.SQLDB_PORT),
    user: process.env.SQLDB_USERNAME,
    password: process.env.SQLDB_PASSWORD,
    database: process.env.SQLDB_DATABASE,
    options: {
        trustServerCertificate: true,
    },
};

const pool = await sql.connect(config);

// Use pool to query the database...
```

Or use the connection URI directly:

```typescript title="TypeScript — Connect with URI"
import sql from 'mssql';

const pool = await sql.connect(process.env.SQLDB_URI!);
```
**Tip:** If your app expects specific environment variable names different from the Aspire defaults, you can pass individual connection properties from the AppHost. See [Pass custom environment variables](../sql-server-host/#pass-custom-environment-variables) in the Hosting integration reference.