Compartilhar via


integração .NET AspireSQL ServerEntity Framework Core

Inclui:Integração de hospedagem incluída —&— Client Integração incluídaClient

SQL Server é um sistema de gerenciamento de banco de dados relacional desenvolvido pela Microsoft. A integração .NET AspireSQL ServerEntity Framework Core permite que você se conecte a instâncias existentes SQL Server ou crie novas instâncias a partir de .NET com a imagem de contêiner mcr.microsoft.com/mssql/server.

Integração de hospedagem

A integração de hospedagem SQL Server modela o servidor como o tipo SqlServerServerResource e o banco de dados como o tipo SqlServerDatabaseResource. Para acessar esses tipos e APIs, adicione o pacote NuGet 📦Aspire.Hosting.SqlServer no projeto do host do aplicativo .

dotnet add package Aspire.Hosting.SqlServer

Para obter mais informações, consulte dotnet add package ou Gerencie dependências de pacotes em aplicativos .NET.

Adicionar recurso SQL Server e recurso de banco de dados

No projeto de host do aplicativo, chame AddSqlServer para adicionar e retornar um gerador de recursos SQL Server. Encadear uma chamada ao construtor do recurso retornado para AddDatabase, a fim de adicionar o recurso de banco de dados SQL Server.

var builder = DistributedApplication.CreateBuilder(args);

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

var db = sql.AddDatabase("database");

builder.AddProject<Projects.ExampleProject>("exampleproject")
       .WithReference(db)
       .WaitFor(db);

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

builder.Build().Run();

Observação

O contêiner SQL Server é lento para iniciar, portanto, é melhor usar um ciclo de vida persistente para evitar reinicializações desnecessárias. Para obter mais informações, consulte Tempo de Vida do Recurso de Contêiner.

Quando .NET.NET Aspire adiciona uma imagem de contêiner ao host do aplicativo, conforme mostrado no exemplo anterior com a imagem mcr.microsoft.com/mssql/server, ele cria uma nova instância de SQL Server em seu computador local. Uma referência ao construtor de recursos SQL Server (a variável sql) é usada para adicionar um banco de dados. O banco de dados é nomeado database e, em seguida, adicionado ao ExampleProject.

Ao adicionar um recurso de banco de dados ao modelo de aplicativo, o banco de dados será criado se ele ainda não existir. A criação do banco de dados depende das APIs de evento do host do aplicativo, especificamente ResourceReadyEvent. Em outras palavras, quando o sql recurso estiver pronto, o evento será gerado e o recurso de banco de dados será criado.

O recurso SQL Server inclui credenciais padrão com um username de sa e um password aleatório gerado usando o método CreateDefaultPasswordParameter.

Quando o host do aplicativo é executado, a senha é armazenada no repositório secreto do host do aplicativo. Ele é adicionado à seção Parameters, por exemplo:

{
  "Parameters:sql-password": "<THE_GENERATED_PASSWORD>"
}

O nome do parâmetro é sql-password, mas na verdade é apenas formatar o nome do recurso com um sufixo -password. Para obter mais informações, consulte Armazenamento seguro de segredos do aplicativo no desenvolvimento em ASP.NET Core e Adicionar SQL Server recurso com parâmetros.

O método WithReference configura uma conexão no ExampleProject denominado database.

Dica

Se você preferir se conectar a um SQL Serverexistente, chame AddConnectionString em vez disso. Para obter mais informações, consulte Consultar recursos existentes.

Adicionar o recurso SQL Server com scripts de banco de dados

Por padrão, quando você adiciona um SqlServerDatabaseResource, ele depende do seguinte script SQL para criar o banco de dados:

IF
(
    NOT EXISTS
    (
        SELECT 1
        FROM sys.databases
        WHERE name = @DatabaseName
    )
)
CREATE DATABASE [<QUOTED_DATABASE_NAME>];

Para alterar o script padrão, encadeia uma chamada para o WithCreationScript método no construtor de recursos do banco de dados:

var builder = DistributedApplication.CreateBuilder(args);

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

var databaseName = "app-db";
var creationScript = $$"""
    IF DB_ID('{{databaseName}}') IS NULL
        CREATE DATABASE [{{databaseName}}];
    GO

    -- Use the database
    USE [{{databaseName}}];
    GO

    -- Create the todos table
    CREATE TABLE todos (
        id INT PRIMARY KEY IDENTITY(1,1),        -- Unique ID for each todo
        title VARCHAR(255) NOT NULL,             -- Short description of the task
        description TEXT,                        -- Optional detailed description
        is_completed BIT DEFAULT 0,              -- Completion status
        due_date DATE,                           -- Optional due date
        created_at DATETIME DEFAULT GETDATE()    -- Creation timestamp
    );
    GO

    """;

var db = sql.AddDatabase(databaseName)
            .WithCreationScript(creationScript);

builder.AddProject<Projects.AspireApp_ExampleProject>("exampleproject")
       .WithReference(db)
       .WaitFor(db);

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

builder.Build().Run();

O exemplo anterior cria um banco de dados nomeado app_db com uma única todos tabela. O script SQL é executado quando o recurso de banco de dados é criado. O script é passado como uma cadeia de caracteres para o WithCreationScript método, que é executado no contexto do SQL Server recurso.

Adicionar recurso SQL Server com volume de dados

Para adicionar um volume de dados ao recurso SQL Server, chame o método WithDataVolume no recurso SQL Server:

var builder = DistributedApplication.CreateBuilder(args);

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

var db = sql.AddDatabase("database");

builder.AddProject<Projects.AspireApp_ExampleProject>("exampleproject")
       .WithReference(db)
       .WaitFor(db);

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

builder.Build().Run();

O volume de dados é utilizado para armazenar permanentemente os dados de SQL Server, fora do ciclo de vida do contêiner. O volume de dados é montado no caminho /var/opt/mssql no contêiner SQL Server e, quando um parâmetro name não é fornecido, o nome é gerado aleatoriamente. Para obter mais informações sobre volumes de dados e detalhes sobre por que eles são preferidos em vez de bind mounts, consulte a documentação Docker: Volumes.

Aviso

A senha é armazenada no volume de dados. Ao usar um volume de dados e se a senha for alterada, ela não funcionará até que você exclua o volume.

Adicionar recurso SQL Server com vinculação de dados

Para adicionar uma montagem de associação de dados ao recurso SQL Server, chame o método WithDataBindMount.

var builder = DistributedApplication.CreateBuilder(args);

var sql = builder.AddSqlServer("sql")
                 .WithDataBindMount(source: @"C:\SqlServer\Data");

var db = sql.AddDatabase("database");

builder.AddProject<Projects.AspireApp_ExampleProject>("exampleproject")
       .WithReference(db)
       .WaitFor(db);

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

builder.Build().Run();

Importante

Montagens de ligação de dados têm funcionalidade limitada em comparação com volumes , os quais oferecem melhor desempenho, portabilidade e segurança, o que os torna mais adequados para ambientes de produção. No entanto, os "bind mounts" permitem acesso direto e modificação de arquivos no sistema de hospedagem, ideal para desenvolvimento e testes, onde são necessárias alterações em tempo real.

As montagens de vinculação de dados dependem do sistema de arquivos da máquina host para persistir os dados SQL Server entre reinicializações de contêiner. A montagem de vinculação de dados é efetuada no caminho C:\SqlServer\Data no Windows (ou /SqlServer/Data no Unix) no computador host dentro do contêiner SQL Server. Para obter mais informações sobre montagens de vinculação de dados, consulte a documentação em Docker: Montagens de vinculação.

Adicionar SQL Server recurso com parâmetros

Quando quiser fornecer explicitamente a senha usada pela imagem de contêiner, você pode fornecer essas credenciais como parâmetros. Considere o seguinte exemplo alternativo:

var builder = DistributedApplication.CreateBuilder(args);

var password = builder.AddParameter("password", secret: true);

var sql = builder.AddSqlServer("sql", password);
var db = sql.AddDatabase("database");

builder.AddProject<Projects.AspireApp_ExampleProject>("exampleproject")
       .WithReference(db)
       .WaitFor(db);

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

builder.Build().Run();

Para obter mais informações sobre como fornecer parâmetros, consulte Parâmetros externos.

Conectar-se aos recursos do banco de dados

Quando o host do aplicativo .NET.NET Aspire é executado, os recursos de banco de dados do servidor podem ser acessados de ferramentas externas, como SQL Server Management Studio) ou MSSQL para Visual Studio Code. A cadeia de conexão para o recurso de banco de dados está disponível nas variáveis de ambiente dos recursos dependentes e pode ser acessada usando o painel .NET.NET Aspire: painel Detalhes do Recurso. A variável de ambiente é nomeada ConnectionStrings__{name} em que {name} é o nome do recurso de banco de dados, neste exemplo é database. Use a cadeia de conexão para se conectar ao recurso de banco de dados a partir de ferramentas externas. Imagine que você tenha um banco de dados chamado todos com uma única tabela de dbo.Todos.

Para se conectar ao recurso de banco de dados do SQL Server Management Studio, siga estas etapas:

  1. Abra o SSMS.

  2. Na caixa de diálogo Conectar ao Server, selecione a guia Parâmetros de Conexão Adicionais.

  3. Cole a cadeia de conexão no campo Parâmetros de Conexão Adicionais e selecione Conectar.

    SQL Server Management Studio: conectar à janela de conexão Server.

  4. Se estiver conectado, você poderá ver o recurso de banco de dados no Explorador de Objetos:

    SQL Server Management Studio: conectado ao banco de dados.

Para obter mais informações, consulte SQL Server Management Studio: Conectar-se a um servidor.

Verificações de integridade das integrações de hospedagem

A integração de hospedagem SQL Server adiciona automaticamente uma verificação de integridade para o recurso de SQL Server. A verificação de integridade verifica se o SQL Server está em execução e se uma conexão pode ser estabelecida com ele.

A integração de hospedagem depende do pacote NuGet 📦 AspNetCore.HealthChecks.SqlServer.

integração Client

Para começar com a .NET AspireSQL ServerEntity Framework Core integração, instale o pacote NuGet 📦Aspire.Microsoft.EntityFrameworkCore.SqlServer no projeto que utiliza o cliente, ou seja, o projeto para o aplicativo que usa o SQL ServerEntity Framework Core cliente.

dotnet add package Aspire.Microsoft.EntityFrameworkCore.SqlServer

Para obter mais informações, consulte dotnet add package ou Gerencie dependências de pacotes em aplicativos .NET.

Adicionar contexto de banco de dados SQL Server

No arquivo Program.cs do projeto que utiliza o cliente, chame o método de extensão AddSqlServerDbContext em qualquer IHostApplicationBuilder para registrar um DbContext para que possa ser usado por meio do contêiner de injeção de dependência. O método usa um parâmetro de nome de conexão.

builder.AddSqlServerDbContext<ExampleDbContext>(connectionName: "database");

Dica

O parâmetro connectionName deve corresponder ao nome usado ao adicionar o recurso de banco de dados SQL Server no projeto de host do aplicativo. Em outras palavras, quando você chama AddDatabase e fornece um nome de database esse mesmo nome deve ser usado ao chamar AddSqlServerDbContext. Para obter mais informações, consulte adicionar o recurso SQL Server e o recurso de banco de dados.

Para recuperar o objeto ExampleDbContext de um serviço:

public class ExampleService(ExampleDbContext context)
{
    // Use context...
}

Para obter mais informações sobre injeção de dependência, consulte .NET injeção de dependência.

Enriquecer um contexto de banco de dados SQL Server

Você pode preferir usar o método Entity Framework padrão para obter um contexto de banco de dados e adicioná-lo ao contêiner de injeção de dependência:

builder.Services.AddDbContext<ExampleDbContext>(options =>
    options.UseSqlServer(builder.Configuration.GetConnectionString("database")
        ?? throw new InvalidOperationException("Connection string 'database' not found.")));

Observação

O nome da cadeia de conexão que você passa para o GetConnectionString método deve corresponder ao nome usado ao adicionar o recurso do SQL Server no projeto de host do aplicativo. Para obter mais informações, consulte adicionar o recurso SQL Server e o recurso de banco de dados.

Você tem mais flexibilidade ao criar o contexto do banco de dados dessa maneira, por exemplo:

  • Você pode reutilizar o código de configuração existente para o contexto do banco de dados sem reescrevê-lo para .NET.NET Aspire.
  • Você pode usar Entity Framework Core interceptores para modificar operações de banco de dados.
  • Você pode optar por não usar a agregação de contexto Entity Framework Core, o que pode ter um desempenho melhor em algumas circunstâncias.

Se você usar esse método, poderá aprimorar o contexto do banco de dados com repetições de estilo .NET.NET Aspire, verificações de integridade, registro em log e recursos de telemetria chamando o método EnrichSqlServerDbContext:

builder.EnrichSqlServerDbContext<ExampleDbContext>(
    configureSettings: settings =>
    {
        settings.DisableRetry = false;
        settings.CommandTimeout = 30; // seconds
    });

O parâmetro settings é uma instância da classe MicrosoftEntityFrameworkCoreSqlServerSettings.

Configuração

A integração .NET AspireSQL ServerEntity Framework Core fornece várias abordagens de configuração e opções para atender aos requisitos e convenções do seu projeto.

Usar a cadeia de conexão

Ao usar uma cadeia de conexão da seção de configuração ConnectionStrings, você fornece o nome da cadeia de conexão ao chamar builder.AddSqlServerDbContext<TContext>():

builder.AddSqlServerDbContext<ExampleDbContext>("sql");

A cadeia de conexão é recuperada da seção de configuração do ConnectionStrings:

{
  "ConnectionStrings": {
    "sql": "Data Source=myserver;Initial Catalog=master"
  }
}

O EnrichSqlServerDbContext não usará a seção de configuração de ConnectionStrings, pois espera que um DbContext seja registrado no ponto em que é chamado.

Para obter mais informações, consulte o ConnectionString.

Usar provedores de configuração

A integração .NET AspireSQL ServerEntity Framework Core dá suporte a Microsoft.Extensions.Configuration. Ele carrega o MicrosoftEntityFrameworkCoreSqlServerSettings de arquivos de configuração, como appsettings.json usando a chave Aspire:Microsoft:EntityFrameworkCore:SqlServer. Se você tiver configurado suas configurações na seção Aspire:Microsoft:EntityFrameworkCore:SqlServer, poderá simplesmente chamar o método sem passar nenhum parâmetro.

Veja a seguir um exemplo de um appsettings.json arquivo que configura algumas das opções disponíveis:

{
  "Aspire": {
    "Microsoft": {
      "EntityFrameworkCore": {
        "SqlServer": {
          "ConnectionString": "YOUR_CONNECTIONSTRING",
          "DbContextPooling": true,
          "DisableHealthChecks": true,
          "DisableTracing": true,
          "DisableMetrics": false
        }
      }
    }
  }
}

Usar configurações integradas

Você também pode passar o delegado Action<MicrosoftEntityFrameworkCoreSqlServerSettings> para configurar algumas ou todas as opções diretamente, por exemplo, para desativar as métricas:

builder.AddSqlServerDbContext<YourDbContext>(
    "sql",
    static settings =>
        settings.DisableMetrics = true);

Configurar várias conexões DbContext

Se você quiser registrar mais de uma DbContext com configuração diferente, poderá usar o nome da seção de configuração $"Aspire.Microsoft.EntityFrameworkCore.SqlServer:{typeof(TContext).Name}". A configuração json seria semelhante a:

{
  "Aspire": {
    "Microsoft": {
      "EntityFrameworkCore": {
          "SqlServer": {
            "ConnectionString": "YOUR_CONNECTIONSTRING",
            "DbContextPooling": true,
            "DisableHealthChecks": true,
            "DisableTracing": true,
            "DisableMetrics": false,
          "AnotherDbContext": {
            "ConnectionString": "AnotherDbContext_CONNECTIONSTRING",
            "DisableTracing": false
          }
        }
      }
    }
  }
}

Em seguida, chamar o método AddSqlServerDbContext com o parâmetro de tipo AnotherDbContext carregaria as configurações da seção Aspire:Microsoft:EntityFrameworkCore:SqlServer:AnotherDbContext.

builder.AddSqlServerDbContext<AnotherDbContext>("another-sql");

Opções de configuração

Aqui estão as opções configuráveis com valores padrão correspondentes:

Nome Descrição
ConnectionString A cadeia de conexão do banco de dados SQL Server ao qual se conectar.
DbContextPooling Um valor booliano que indica se o contexto do banco de dados será criado em pool ou explicitamente sempre que solicitado
MaxRetryCount O número máximo de tentativas de repetição. O valor padrão é 6, defina-o como 0 para desabilitar o mecanismo de repetição.
DisableHealthChecks Um valor booliano que indica se a verificação de integridade do banco de dados está desabilitada ou não.
DisableTracing Um valor booliano que indica se o rastreamento de OpenTelemetry está desabilitado ou não.
DisableMetrics Um valor booliano que indica se as métricas de OpenTelemetry estão desabilitadas ou não.
Timeout O tempo em segundos para aguardar a execução do comando.

Client verificações de saúde de integração

Por padrão, .NET.NET Aspireintegrações de clientes têm verificações de saúde habilitadas para todos os serviços. Da mesma forma, muitas integrações de hospedagem .NET.NET Aspire também habilitam endpoints para verificação de saúde. Para obter mais informações, consulte:

Por padrão, a integração do .NET Aspire Sql ServerEntity Framework Core lida com o seguinte:

  • Adiciona o DbContextHealthCheck, que chama o método EF Core de CanConnectAsync. O nome da verificação de saúde é o nome do tipo TContext.
  • Integra-se ao endpoint HTTP /health, que especifica que todas as verificações de integridade registradas devem ser realizadas com sucesso para que o aplicativo seja considerado pronto para aceitar tráfego.

Observabilidade e telemetria

.NET .NET Aspire integrações configuram automaticamente Registro, Rastreamento e Métricas, que às vezes são conhecidos como os pilares da observabilidade. Para obter mais informações sobre a observabilidade e a telemetria de integração, consulte .NET.NET Aspire visão geral das integrações. Dependendo do serviço de backup, algumas integrações só podem dar suporte a alguns desses recursos. Por exemplo, algumas integrações dão suporte a registro em log e rastreamento, mas não a métricas. Os recursos de telemetria também podem ser desabilitados usando as técnicas apresentadas na seção Configuration.

Registro

A integração .NET AspireSQL ServerEntity Framework Core usa as seguintes categorias de Log:

  • Microsoft.EntityFrameworkCore.ChangeTracking
  • Microsoft.EntityFrameworkCore.Database.Command
  • Microsoft.EntityFrameworkCore.Database.Connection
  • Microsoft.EntityFrameworkCore.Database.Transaction
  • Microsoft.EntityFrameworkCore.Infrastructure
  • Microsoft.EntityFrameworkCore.Migrations
  • Microsoft.EntityFrameworkCore.Model
  • Microsoft.EntityFrameworkCore.Model.Validation
  • Microsoft.EntityFrameworkCore.Query
  • Microsoft.EntityFrameworkCore.Update

Rastreamento

A integração .NET AspireSQL ServerEntity Framework Core emitirá as seguintes atividades de rastreamento usando OpenTelemetry:

  • "OpenTelemetry. Instrumentation.EntityFrameworkCore"

Métricas

A integração .NET AspireSQL ServerEntity Framework Core emitirá as seguintes métricas usando OpenTelemetry:

  • Microsoft.EntityFrameworkCore:
    • ec_Microsoft_EntityFrameworkCore_active_db_contexts
    • ec_Microsoft_EntityFrameworkCore_total_queries
    • ec_Microsoft_EntityFrameworkCore_queries_per_second
    • ec_Microsoft_EntityFrameworkCore_total_save_changes
    • ec_Microsoft_EntityFrameworkCore_save_changes_per_second
    • ec_Microsoft_EntityFrameworkCore_compiled_query_cache_hit_rate
    • ec_Microsoft_Entity_total_execution_strategy_operation_failures
    • ec_Microsoft_E_execution_strategy_operation_failures_per_second
    • ec_Microsoft_EntityFramew_total_optimistic_concurrency_failures
    • ec_Microsoft_EntityF_optimistic_concurrency_failures_per_second

Consulte também