Armazenar dados em bancos de dados em conformidade com o SQL
A pilha do .NET Aspire foi criada para aumentar sua produtividade e ajudar no desenvolvimento de aplicativos web robustos, escalonáveis e seguros. Você pode armazenar dados relacionais estruturados de forma rápida adicionando um dos componentes Aspire compatíveis.
Os componentes atuais dos bancos de dados em conformidade com SQL são:
- Bancos de dados PostgreSQL
- Bancos de dados SQL
- Bancos de dados Oracle
- Bancos de dados MySQL
Observação
A Microsoft pode incluir suporte para outros sistemas de banco de dados e terceiros também podem contribuir, portanto, essa lista pode aumentar.
Nesta unidade, você vai aprender sobre três desses componentes, quais bancos de dados são compatíveis com o Entity Framework Core e como utilizá-los para armazenar e acessar dados.
Como adicionar um componente de banco de dados ao seu projeto
Não importa qual banco de dados você escolha, o processo para adicionar um componente de banco de dados.NET Aspire ao seu projeto é sempre o mesmo.
No projeto do host de aplicativo:
- Instale o componente de hospedagem .NET Aspire no projeto do host de aplicativo.
- Registre um banco de dados e crie um contêiner para ele no host de aplicativo da solução.
- Forneça uma referência para os projetos que precisam de acesso ao contêiner criado que hospeda o banco de dados.
Nos projetos que usam o banco de dados:
- Adicione o componente .NET Aspire com um pacote NuGet aos projetos que precisam acesso aos dados. Opcionalmente, se existir um componente .NET Core Entity Framework (EF) , você poderá usá-lo.
- Registre a fonte de dados ou o contexto do banco de dados para EF no arquivo Program.cs do projeto.
- Use a injeção de dependência para injetar a fonte de dados em seus serviços.
Vamos analisar as especificidades de como executar essas etapas para cada um dos bancos de dados compatíveis.
Como usar os componentes .NET Aspire PostgreSQL
Os componentes .NET Aspire PostgreSQL necessitam de modificações tanto no projeto do host de aplicativo quanto nos microsserviços que usam os bancos de dados.
Como configurar o host de aplicativo
Comece instalando o componente de hospedagem adequado no host de aplicativo:
dotnet add package Aspire.Hosting.PostgreSQL --prerelease
Depois, para registrar um banco de dados e criar um contêiner para ele, insira este código no arquivo Program.cs do host de aplicativo:
var postgres = builder.AddPostgres("postgres");
var postgresdb = postgres.AddDatabase("postgresdb");
Você também precisa fornecer uma referência ao serviço de banco de dados para qualquer projeto que o consume:
var northernTradersCatalogAPI = builder.AddProject<Projects.NorthernTraders_CatalogAPI>()
.WithReference(postgresdb);
Como configurar os projetos de consumo
Para instalar o componente .NET Aspire PostgreSQL, use um comando como esse em seus projetos .NET Aspire:
dotnet add package Aspire.Npgsql --prerelease
Ou, para usar o componente .NET Aspire PostgreSQL Entity Framework Core, use esse comando:
dotnet add package Aspire.Npgsql.EntityFrameworkCore.PostgreSQL --prerelease
Como alternativa, você pode usar o atalho Adicionar > Componente do .NET Aspire no Visual Studio para instalar o componente do gerenciador de pacotes NuGet:
O código no arquivo Program.cs do projeto *.AppHost cria o banco de dados e o fornece para os projetos que querem usá-lo:
var postgres = builder.AddPostgres("pg")
.AddDatabase("postgresdb");
var exampleProject = builder.AddProject<Projects.SampleProject>()
.WithReference(postgres);
Alguns componentes do banco de dados .NET Aspire também permitem criar um contêiner para ferramentas de gerenciamento de banco de dados. Para adicionar o PgAdmin à sua solução e gerenciar o banco de dados PostgreSQL, use este código:
var postgresdb = builder.AddPostgres("pg")
.AddDatabase("postgresdb")
.WithPgAdmin();
A vantagem de permitir que o .NET Aspire crie o contêiner é que você não precisa configurar a conexão do PgAdmin com o banco de dados PostgreSQL, pois tudo é feito de forma automática.
Como usar um banco de dados PostgreSQL
Em qualquer projeto em que você queira usar o banco de dados, adicione uma fonte de dados para representar a conexão com o PostgreSQL. No arquivo Program.cs, este código registra o banco de dados:
builder.AddNpgsqlDataSource("postgresdb");
Ou para usar o componente Entity Framework Core, registre o contexto do banco de dados:
builder.AddNpgsqlDbContext<YourDbContext>("postgresdb");
Após registrar o banco de dados no projeto que o utiliza, você pode interagir com a fonte de dados sempre que precisar, usando a injeção de dependências:
public class YourService(NpgsqlDataSource dataSource)
{
public async Task<IEnumerable<Catalog>> GetCatalog()
{
const string query = "SELECT * FROM catalog";
using var dbConnection = dataSource.OpenConnection();
var results = await dbConnection.QueryAsync<Catalog>(command);
return queryResult.ToArray();
}
}
Ou então, você pode recuperar o contexto YourDbContext
do banco de dados para interagir com ele:
public class YourService(YourDbContext context)
{
public async Task<IEnumerable<Catalog>> GetCatalog()
{
var items = await context.ObjectItems;
if (item is null)
{
return Results.NotFound();
}
else
{
return items;
}
}
}
Como configurar o componente PostgreSQL
A pilha do .NET Aspire tenta reduzir a quantidade de configurações que você precisa fazer. Com a injeção de dependências e a descoberta de serviços, você pode acessar o banco de dados sem a necessidade de configurar as cadeias de conexão nos seus projetos.
Utilizar o projeto do host de aplicativo para criar o contêiner do banco de dados e fornecê-lo como referência aos projetos permite que os projetos receptores acessem a localização do banco de dados, as cadeias de conexão e as portas. Não é necessário gerenciar variáveis de ambiente ou arquivos appsettings.json.
No entanto, se desejar ou precisar de mais controle sobre a configuração do banco de dados, existem outras opções.
Usando uma cadeia de conexão
No projeto que necessita do banco de dados, você utiliza uma cadeia de conexão para se conectar ao banco de dados. Esse método é útil quando você precisa se conectar a um banco de dados que não está registrado no host de aplicativo.
builder.AddNpgsqlDataSource("NpgsqlConnectionString");
Então, no arquivo de configuração, você pode adicionar a cadeia de conexão:
{
"ConnectionStrings": {
"NpgsqlConnectionString": "Host=myserver;Database=postgresdb;User id=myuser;Password=mypassword"
}
}
Como usar os provedores de configuração
O .NET Aspire tem um recurso de componentes que lhes permite oferecer suporte a Microsoft.Extensions.Configuration
. O componente PostgreSQL dá suporte a esse recurso e, por padrão, procura configurações usando a chave Aspire:Npgsql
. Em projetos que usam appsettings.json, uma configuração de exemplo poderia ser assim:
{
"Aspire": {
"Npgsql": {
"ConnectionString": "Host=myserver;Database=postgresdb;User id=myuser;Password=mypassword",
"HealthChecks": true,
"Tracing": true,
"Metrics": true
}
}
}
A configuração anterior define a cadeia de conexão, habilitando verificações de integridade, rastreamento e métricas para o componente PostgreSQL. Assim, seu código não precisa mais especificar a cadeia de conexão, basta usar builder.AddNpgsqlDataSource();
.
Se você estiver utilizando o componente PostgreSQL Entity Framework Core, pode usar a chave Aspire:Npgsql:EntityFrameworkCore:PostgreSQL
para configurar o contexto do banco de dados:
{
"Aspire": {
"Npgsql": {
"EntityFrameworkCore": {
"PostgreSQL": {
"ConnectionString": "Host=myserver;Database=postgresdb;User id=myuser;Password=mypassword",
"MaxRetryCount": 0,
"HealthChecks": false,
"Tracing": false
}
}
}
}
}
Para mais informações sobre as opções de configuração do Entity Framework, confira a Documentação do .NET Aspire.
Usando delegados embutidos
A última opção é fornecer um delegado embutido configureSettings
para o método AddNpgsqlDataSource
. Esse delegado permite que você defina as configurações do componente de banco de dados diretamente no código:
builder.AddNpgsqlDataSource(
"postgresdb", static settings => settings.HealthChecks = false);
Usando os componentes.NET Aspire do Banco de Dados SQL
O padrão mencionado é o mesmo para o componente do Banco de Dados SQL. Você faz alterações tanto no projeto do host de aplicativo quanto nos microsserviços que utilizam o serviço de banco de dados.
Como configurar o host de aplicativo
Para instalar o componente de hospedagem do banco de dados SQL, use esse comando:
dotnet add package Aspire.Hosting.SqlServer --prerelease
Para registrar o contêiner e o banco de dados, adicione esse código no arquivo Program.cs do host de aplicativo:
var sql = builder.AddSqlServer("sql");
var sqldb = sql.AddDatabase("sqldb");
Depois, forneça uma referência ao serviço de banco de dados para qualquer projeto que o consume:
var northernTradersCatalogAPI = builder.AddProject<Projects.NorthernTraders_CatalogAPI>()
.WithReference(sqldb);
Como configurar os projetos de consumo
Para instalar o componente .NET Aspire do Banco de Dados SQL, use um comando como esse em seus projetos .NET Aspire:
dotnet add package Aspire.Microsoft.Data.SqlClient --prerelease
Ou, para usar o componente .NET Aspire SqlServer Entity Framework Core, use esse comando:
dotnet add package Aspire.Microsoft.EntityFrameworkCore.SqlServer --prerelease
Esses pacotes NuGet também podem ser adicionados utilizando o atalho Adicionar > Componente .NET Aspire no Visual Studio.
O código no arquivo Program.cs do projeto *.AppHost para acessar o banco de dados é parecido com o exemplo do PostgreSQL:
var sqlServer = builder.AddSqlServer("sql")
.AddDatabase("sqldata");
var myService = builder.AddProject<Projects.MyService>()
.WithReference(sqlServer);
Como usar um banco de dados SQL Server
Nos projetos que precisam de acesso ao SQL, no arquivo Program.cs, esse código faz o registro do contexto do banco de dados Entity Framework:
builder.AddSqlServerDbContext<YourDbContext>("sqldata");
Após registrar o banco de dados no projeto que o utiliza, você pode interagir com o contexto do banco de dados YourDbContext
por meio da injeção de dependências. Esse exemplo de código recupera previsões meteorológicas de um banco de dados e seleciona uma delas aleatoriamente para retornar:
app.MapGet("/weatherforecast", async (YourDbContext context) =>
{
var rng = new Random();
var forecasts = await context.Forecasts.ToListAsync();
var forecast = forecasts[rng.Next(forecasts.Count)];
return forecast;
});
Como configurar o componente do SQL Server
Assim como antes, se você usar o mesmo nome de banco de dados no host de aplicativo e no projeto que o utiliza, não é necessário configurar a conexão entre o banco de dados SQL Server e os projetos. O componente do SQL Server .NET Aspire também oferece outras formas de configuração.
Como usar os provedores de configuração
O componente SQL Server também dá suporte a Microsoft.Extensions.Configuration
. Por padrão, ele busca as configurações usando a chave Aspire:SqlServer:SqlClient
. Em projetos que usam appsettings.json, uma configuração de exemplo poderia ser assim:
{
"Aspire": {
"SqlServer": {
"SqlClient": {
"ConnectionString": "YOUR_CONNECTIONSTRING",
"HealthChecks": true,
"Tracing": false,
"Metrics": false
}
}
}
}
Como usar configurações embutidas
Ao adicionar o componente do SQL Server, você pode fornecer um delegado embutido configureSettings
para o método AddSqlServerClient
. Esse delegado permite que você defina as configurações do componente de banco de dados diretamente no código:
builder.AddSqlServerClient("sqldata", static settings => settings.HealthChecks = false);
Você pode fornecer qualquer uma das opções com suporte:
ConnectionString
: a cadeia de conexão do banco de dados SQL ServerHealthChecks
: um valor booliano que indica se a verificação de integridade do banco de dados está habilitadaTracing
: um valor booliano que indica se o rastreamento OpenTelemetry está habilitadoMetrics
: um valor booliano que indica se as métricas OpenTelemetry estão habilitadas
Como conectar-se a vários bancos de dados
O componente do SQL Server dá suporte a várias conexões por meio de instâncias nomeadas. Por exemplo, você pode se conectar a dois bancos de dados SQL Server diferentes no mesmo projeto:
{
"Aspire": {
"SqlServer": {
"SqlClient": {
"INSTANCE_1": {
"ServiceUri": "YOUR_URI",
"HealthChecks": false
},
"INSTANCE_2": {
"ServiceUri": "YOUR_URI",
"HealthChecks": false
}
}
}
}
}
Usando essa configuração, você pode se conectar aos dois bancos de dados diferentes no mesmo projeto:
builder.AddSqlServerClient("INSTANCE_1");
builder.AddSqlServerClient("INSTANCE_2");
Como usar o componente MySQL
Para instalar o componente .NET Aspire MySQL, use um comando como esse em seus projetos .NET Aspire que precisam de acesso aos dados:
dotnet add package Aspire.MySqlConnector --prerelease
Ou então, use o atalho Adicionar > Componente do .NET Aspire no Visual Studio para instalar o componente do gerenciador de pacotes NuGet.
O código no arquivo Program.cs do projeto *.AppHost para acessar o banco de dados é parecido com o exemplo do PostgreSQL:
var mysqldb = builder.AddMySql("mysql")
.AddDatabase("mysqldb")
.WithPhpMyAdmin();
var myService = builder.AddProject<Projects.MyService>()
.WithReference(mysqldb);
Assim como o componente PostgreSQL, o componente MySQL também permite que você crie um contêiner para as ferramentas de gerenciamento de banco de dados. O exemplo anterior adiciona o PhpMyAdmin à solução.
Como usar um banco de dados MySQL
O procedimento é o mesmo nos projetos que precisam de acesso ao MySQL. No arquivo Program.cs, este código registra o banco de dados:
builder.AddMySqlDataSource("mysqldb");
Após registrar o banco de dados no projeto que o utiliza, você pode interagir com a fonte de dados sempre que precisar, usando a injeção de dependências:
app.MapGet("/catalog", async (MySqlConnection db) =>
{
const string sql = """
SELECT Id, Name, Description, Price
FROM catalog
""";
// the db object is a connection to the MySQL database registered with AddMySqlDataSource
return await db.QueryAsync<CatalogItem>(sql);
});
Como configurar o componente MySQL
O componente MySQL dá suporte às mesmas três opções para gerenciar a configuração.
Cadeias de conexão
O arquivo appsettings.json pode conter a cadeia de conexão para o banco de dados MySQL:
{
"ConnectionStrings": {
"MySqConnection": "Server=myserver;Database=mysqldb;Uid=myuser;Pwd=mypassword"
}
}
Então, no seu projeto, você pode se conectar ao banco de dados com a cadeia de conexão usando um código como esse:
builder.AddMySqlDataSource("MySqConnection");
Provedores de configuração
A chave Aspire:MySqlConnector
é usada para configurar o componente MySQL.
{
"Aspire": {
"MySqlConnector": {
"ConnectionString": "Server=myserver;Database=mysqldb;Uid=myuser;Pwd=mypassword",
"HealthChecks": true,
"Tracing": false,
"Metrics": false
}
}
}
Configurações embutidas
builder.AddMySqlDataSource("mysqldb", static settings => settings.HealthChecks = false);
Saiba como propagar seu banco de dados
A pilha do .NET Aspire usa contêineres, aproveitando as vantagens de ambientes padronizados e implantações facilitadas. Uma desvantagem é que os contêineres ficarão sem estado. Quando o contêiner é destruído, você perde todos os dados ou esquemas adicionados a um banco de dados. O .NET Aspire fornece maneiras de propagar seus bancos de dados com dados quando cria seus contêineres.
Como usar volumes e scripts
A forma mais simples de propagar seu banco de dados é usando volumes e scripts SQL. Os volumes podem armazenar dados de diversos contêineres simultaneamente, oferecem alto desempenho e são fáceis de fazer backup ou migrar. Os scripts armazenados nesses volumes são executados quando um contêiner é criado, preenchendo o banco de dados com os dados. O script pode ser um arquivo SQL que contém os dados e o esquema desejados para o seu banco de dados.
Por exemplo, se você tivesse esse script SQL, armazenado em um arquivo chamado postgres-backup.sql, na pasta Service.API/Seed:
CREATE TABLE catalog (
Id INT PRIMARY KEY,
Name VARCHAR(50),
Description VARCHAR(255),
Price DECIMAL(18, 2)
);
INSERT INTO catalog (Id, Name, Description, Price)
VALUES (1, 'Item 1', 'Description of item 1', 10.99),
(2, 'Item 2', 'Description of item 2', 20.99),
(3, 'Item 3', 'Description of item 3', 30.99);
No host de aplicativo da sua solução, você pode vincular a pasta Service.API/Seed à pasta /docker-entrypoint-initdb.d do contêiner. Essa pasta é uma pasta especial no contêiner PostgreSQL que executa todos os scripts SQL encontrados quando o contêiner é criado:
var catalogDB = builder.AddPostgres("postgres")
.WithPgAdmin()
.WithEnvironment("POSTGRES_DB", "backendDB")
.WithBindMount("../Service.API/Seed", "/docker-entrypoint-initdb.d")
.AddDatabase("backendDB");
Você pode até dividir os scripts SQL em scripts de criação de esquema e propagação de dados. Se todos estiverem na pasta Service.API/Seed, eles serão executados quando o .NET Aspire criar o banco de dados.
Como propagar dados usando o Entity Framework Core
Para os componentes que dão suporte ao Entity Framework Core, você pode propagar seu banco de dados usando a classe DbContext
e as migrações do Entity Framework Core. Esse método usa o código C# para propagar o banco de dados. Contudo, essa propagação deve ocorrer somente durante o desenvolvimento ou testes, e não em produção.
// Register DbContext class
builder.AddNpgsqlDbContext<CatalogContext>("sqldata");
var app = builder.Build();
app.MapDefaultEndpoints();
if (app.Environment.IsDevelopment())
{
// Retrieve an instance of the DbContext class and manually run migrations during development
using (var scope = app.Services.CreateScope())
{
var context = scope.ServiceProvider.GetRequiredService<CatalogContext>();
context.Database.EnsureCreated();
}
}
O código acima verifica o estado do ambiente do aplicativo. Se estiver em desenvolvimento, o código recuperará a classe CatalogContext
e executará o método EnsureCreated
. Esse método cria o banco de dados e executa todas as migrações que estejam pendentes.
Para mais informações sobre como propagar os diferentes componentes de banco de dados, confira a Documentação do .NET Aspire.