Speichern von Daten in SQL-konformen Datenbanken

Abgeschlossen

Der .NET Aspire-Stapel wurde entwickelt, um Ihre Produktivität zu steigern und Ihnen bei der Erstellung robuster, skalierbarer und sicherer Webanwendungen zu helfen. Sie können strukturierte relationale Daten schnell speichern, indem Sie eine der unterstützten Aspire-Komponenten hinzufügen.

Aktuelle SQL-kompatible Datenbankkomponenten:

  • PostgreSQL-Datenbanken
  • SQL-Datenbanken
  • Oracle-Datenbanken
  • MySQL-Datenbanken

Hinweis

Microsoft kann Unterstützung für andere Datenbanksysteme hinzufügen, und Dritte können ebenfalls beitragen, sodass diese Liste möglicherweise noch erweitert wird.

In dieser Lerneinheit erfahren Sie mehr über drei dieser Komponenten sowie darüber, welche Datenbanken Entity Framework Core unterstützen und wie sie zum Speichern und Abrufen von Daten verwendet werden.

Hinzufügen einer Datenbankkomponente zu Ihrem Projekt

Unabhängig davon, für welche Datenbank Sie sich entscheiden, ist die Vorgehensweise zum Hinzufügen einer .NET Aspire-Datenbankkomponente zu Ihrem Projekt die gleiche.

Im App-Hostprojekt:

  • Installieren Sie die .NET Aspire-Hostingkomponente im App-Hostprojekt.
  • Registrieren Sie eine Datenbank, und erstellen Sie einen Container dafür im App-Host der Lösung.
  • Übergeben Sie einen Verweis auf die Projekte, die Zugriff auf den erstellten Container benötigen, der die Datenbank hostet.

In den Projekten, die die Datenbank verwenden:

  • Fügen Sie die .NET Aspire-Komponente mit einem NuGet-Paket zu den Projekten hinzu, die Datenzugriff erfordern. Optional gilt: Wenn eine .NET Core EF-Komponente (Entity Framework) vorhanden ist, können Sie stattdessen diese verwenden.
  • Registrieren Sie die Datenquelle oder den Datenbankkontext für EF in der Datei Program.cs des Projekts.
  • Verwenden Sie die Abhängigkeitsinjektion, um die Datenquelle in Ihre Dienste einzufügen.

Sehen wir uns im Einzelnen an, wie Sie diese Schritte für jede unterstützte Datenbank ausführen.

Verwenden der .NET Aspire PostgreSQL-Komponenten

Die .NET Aspire PostgreSQL-Komponenten erfordern Änderungen im App-Hostprojekt sowie in allen Microservices, die die Datenbanken verwenden.

Konfigurieren des App-Hosts

Installieren Sie zunächst die entsprechende Hostingkomponente auf dem App-Host:

dotnet add package Aspire.Hosting.PostgreSQL --prerelease

Fügen Sie anschließend zum Registrieren einer Datenbank und zum Erstellen eines Containers dafür in der Datei Program.cs des App-Hosts den folgenden Code hinzu:

var postgres = builder.AddPostgres("postgres");
var postgresdb = postgres.AddDatabase("postgresdb");

Sie müssen auch einen Verweis auf den Datenbankdienst an alle Projekte übergeben, die ihn nutzen:

var northernTradersCatalogAPI = builder.AddProject<Projects.NorthernTraders_CatalogAPI>()
                                       .WithReference(postgresdb);

Konfigurieren der zugreifenden Projekte

Um die .NET Aspire PostgreSQL-Komponente zu installieren, verwenden Sie einen Befehl wie diesen in Ihren .NET Aspire-Projekten:

dotnet add package Aspire.Npgsql --prerelease

Oder verwenden Sie stattdessen den folgenden Befehl, um die .NET Aspire PostgreSQL Entity Framework Core-Komponente zu nutzen:

dotnet add package Aspire.Npgsql.EntityFrameworkCore.PostgreSQL --prerelease

Alternativ können Sie die Verknüpfung Hinzufügen > .NET Aspire-Komponente in Visual Studio verwenden, um die Komponente über den NuGet-Paket-Manager zu installieren:

Screenshot: NuGet-Paket-Manager in Visual Studio mit .NET Aspire PostgreSQL-Komponenten

Code in der Datei Program.cs des Projekts *.AppHost erstellt die Datenbank und übergibt sie an Projekte, die sie nutzen möchten:

var postgres = builder.AddPostgres("pg")
                      .AddDatabase("postgresdb");

var exampleProject = builder.AddProject<Projects.SampleProject>()
                            .WithReference(postgres);

Einige der .NET Aspire-Datenbankkomponenten ermöglichen Ihnen auch das Erstellen eines Containers für Datenbankverwaltungstools. Wenn Sie Ihrer Lösung PgAdmin hinzufügen möchten, um die PostgreSQL-Datenbank zu verwalten, verwenden Sie den folgenden Code:

var postgresdb = builder.AddPostgres("pg")
                        .AddDatabase("postgresdb")
                        .WithPgAdmin();

Wenn Sie .NET Aspire den Container erstellen lassen, hat dies den Vorteil, dass Sie keine Konfiguration durchführen müssen, um PgAdmin mit der PostgreSQL-Datenbank zu verbinden. Alles geschieht automatisch.

Verwenden einer PostgreSQL-Datenbank

In jedem Projekt, in dem Sie die Datenbank verwenden möchten, fügen Sie eine Datenquelle hinzu, um die Verbindung mit PostgreSQL darzustellen. In der Datei Program.cs registriert dieser Code die Datenbank:

builder.AddNpgsqlDataSource("postgresdb");

Oder registrieren Sie den Datenbankkontext, um die Entity Framework Core-Komponente zu verwenden:

builder.AddNpgsqlDbContext<YourDbContext>("postgresdb");

Sobald die Datenbank im zugreifenden Projekt registriert ist, können Sie jederzeit bei Bedarf mit der Datenquelle interagieren, indem Sie Abhängigkeitsinjektion verwenden:

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();
	}
}

Alternativ können Sie den Datenbankkontext YourDbContext abrufen, um mit der Datenbank zu interagieren:

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;
		}
	}
}

Konfigurieren der PostgreSQL-Komponente

Der .NET Aspire-Stapel versucht, den für Sie erforderlichen Konfigurationsaufwand zu reduzieren. Mithilfe von Abhängigkeitsinjektion und Dienstermittlung können Sie auf die Datenbank zugreifen, ohne die Verbindungszeichenfolgen in Ihren Projekten konfigurieren zu müssen.

Wenn Sie das App-Hostprojekt verwenden, um den Datenbankcontainer zu erstellen und als Verweis auf die Projekte zu übergeben, können die empfangenden Projekte auf den Datenbankspeicherort, Verbindungszeichenfolgen und Ports zugreifen. Es ist nicht erforderlich, Umgebungsvariablen oder Dateien vom Typ appsettings.json zu verwalten.

Wenn Sie aber mehr Kontrolle über die Konfiguration der Datenbank möchten oder benötigen, gibt es weitere Optionen.

Verwendung einer Verbindungszeichenfolge

In dem Projekt, für das die Datenbank erforderlich ist, verwenden Sie eine Verbindungszeichenfolge, um eine Verbindung mit der Datenbank herzustellen. Dieser Ansatz ist nützlich, wenn Sie eine Verbindung mit einer Datenbank herstellen müssen, die nicht im App-Host registriert ist.

builder.AddNpgsqlDataSource("NpgsqlConnectionString");

Dann können Sie in der Konfigurationsdatei die Verbindungszeichenfolge hinzufügen:

{
  "ConnectionStrings": {
    "NpgsqlConnectionString": "Host=myserver;Database=postgresdb;User id=myuser;Password=mypassword"
  }
}

Verwenden von Konfigurationsanbietern

.NET Aspire verfügt über eine Funktion von Komponenten, mit denen sie Microsoft.Extensions.Configuration unterstützen können. Die PostgreSQL-Komponente unterstützt diese Funktion und sucht standardmäßig mithilfe des Aspire:Npgsql-Schlüssels nach Einstellungen. In Projekten mit appsettings.json sieht eine Beispielkonfiguration möglicherweise wie folgt aus:

{
  "Aspire": {
    "Npgsql": {
      "ConnectionString": "Host=myserver;Database=postgresdb;User id=myuser;Password=mypassword",
      "HealthChecks": true,
      "Tracing": true,
      "Metrics": true
    }
  }
}

Die vorherige Konfiguration legt die Verbindungszeichenfolge fest, wodurch Integritätsprüfungen, Ablaufverfolgung und Metriken für die PostgreSQL-Komponente aktiviert werden. Ihr Code muss dann die Verbindungszeichenfolge nicht mehr angeben, sondern nur builder.AddNpgsqlDataSource(); verwenden.

Wenn Sie die PostgreSQL Entity Framework Core-Komponente verwenden, können Sie den Schlüssel Aspire:Npgsql:EntityFrameworkCore:PostgreSQL verwenden, um den Datenbankkontext zu konfigurieren:

{
  "Aspire": {
    "Npgsql": {
      "EntityFrameworkCore": {
        "PostgreSQL": {
          "ConnectionString": "Host=myserver;Database=postgresdb;User id=myuser;Password=mypassword",
          "MaxRetryCount": 0,
          "HealthChecks": false,
          "Tracing": false
        }
      }
    }
  }
}

Weitere Informationen zu den Entity Framework-Konfigurationsoptionen finden Sie in der Dokumentation zu .NET Aspire.

Verwenden von Inlinedelegaten

Die letzte Option besteht darin, einen Inlinedelegaten vom Typ configureSettings an die AddNpgsqlDataSource-Methode zu übergeben. Mit diesem Delegaten können Sie die Einstellungen für die Datenbankkomponente direkt mit Code konfigurieren:

builder.AddNpgsqlDataSource(
    "postgresdb", static settings => settings.HealthChecks = false);

Verwenden der SQL-Datenbank-Komponenten für .NET Aspire

Das vorherige Muster ist für die Komponente für SQL-Datenbank identisch. Sie nehmen Änderungen sowohl im App-Hostprojekt als auch in den Microservices vor, die den Datenbankdienst nutzen.

Konfigurieren des App-Hosts

Verwenden Sie den folgenden Befehl, um die Hostingkomponente für SQL-Datenbank zu installieren:

dotnet add package Aspire.Hosting.SqlServer --prerelease

Fügen Sie dann zum Registrieren des Containers und der Datenbank den folgenden Code zur Datei Program.cs des App-Hosts hinzu:

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

Anschließend übergeben Sie einen Verweis auf den Datenbankdienst an alle Projekte übergeben, die ihn nutzen:

var northernTradersCatalogAPI = builder.AddProject<Projects.NorthernTraders_CatalogAPI>()
                                       .WithReference(sqldb);

Konfigurieren der zugreifenden Projekte

Um die SQL-Datenbank-Komponente für .NET Aspire zu installieren, verwenden Sie einen Befehl wie diesen in Ihren .NET Aspire-Projekten:

dotnet add package Aspire.Microsoft.Data.SqlClient --prerelease

Oder verwenden Sie stattdessen den folgenden Befehl, um die .NET Aspire Entity Framework Core-Komponente „SqlServer“ zu nutzen:

dotnet add package Aspire.Microsoft.EntityFrameworkCore.SqlServer --prerelease

Diese NuGet-Pakete können auch über die Verknüpfung Hinzufügen > .NET Aspire-Komponente in Visual Studio hinzugefügt werden.

Die Datei Program.cs des Projekts *.AppHost zum Zugreifen auf die Datenbank ähnelt dem PostgreSQL-Beispiel:

var sqlServer = builder.AddSqlServer("sql")
                       .AddDatabase("sqldata");

var myService = builder.AddProject<Projects.MyService>()
                       .WithReference(sqlServer);

Verwenden einer SQL Server-Datenbank

In den Projekten, die SQL-Zugriff benötigen, registriert dieser Code in der Datei Program.cs den Entity Framework-Datenbankkontext:

builder.AddSqlServerDbContext<YourDbContext>("sqldata");

Sobald die Datenbank im zugreifenden Projekt registriert ist, können Sie mithilfe der Abhängigkeitsinjektion mit dem Datenbankkontext YourDbContext interagieren: Dieser Beispielcode ruft Wettervorhersagen aus einer Datenbank ab und wählt nach dem Zufallsprinzip eine für die Rückgabe aus:

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;
});

Konfigurieren der SQL Server-Komponente

Wie zuvor müssen Sie die Verbindung zwischen Ihrer SQL Server-Datenbank und den Projekten nicht konfigurieren, wenn Sie denselben Datenbanknamen im App-Host und im zugreifenden Projekt verwenden. Die SQL Server-Komponente für .NET Aspire unterstützt auch andere Möglichkeiten zum Konfigurieren der Komponente.

Verwenden von Konfigurationsanbietern

Die SQL Server-Komponente unterstützt auch Microsoft.Extensions.Configuration. Sie sucht standardmäßig mithilfe des Aspire:SqlServer:SqlClient-Schlüssels nach Einstellungen. In Projekten mit appsettings.json sieht eine Beispielkonfiguration möglicherweise wie folgt aus:

{
  "Aspire": {
    "SqlServer": {
      "SqlClient": {
        "ConnectionString": "YOUR_CONNECTIONSTRING",
        "HealthChecks": true,
        "Tracing": false,
        "Metrics": false
      }
    }
  }
}

Verwenden von Inlinekonfigurationen

Wenn Sie die SQL Server-Komponente hinzufügen, können Sie einen configureSettings-Inlinedelegaten an die AddSqlServerClient-Methode übergeben. Mit diesem Delegaten können Sie die Einstellungen für die Datenbankkomponente direkt mit Code konfigurieren:

builder.AddSqlServerClient("sqldata", static settings => settings.HealthChecks = false);

Sie können eine der unterstützten Optionen übergeben:

  • ConnectionString: Die Verbindungszeichenfolge der SQL Server-Datenbank
  • HealthChecks: Ein boolescher Wert, der angibt, ob die Integritätsprüfung für die Datenbank aktiviert ist
  • Tracing: Ein boolescher Wert, der angibt, ob die OpenTelemetry-Ablaufverfolgung aktiviert ist
  • Metrics: Ein boolescher Wert, der angibt, ob die OpenTelemetry-Metrik aktiviert ist

Herstellen einer Verbindung mit mehreren Datenbanken

Die SQL Server-Komponente unterstützt mehrere Verbindungen über benannte Instanzen. Sie können beispielsweise eine Verbindung mit zwei verschiedenen SQL Server-Datenbanken im selben Projekt herstellen:

{
  "Aspire": {
    "SqlServer": {
      "SqlClient": {
        "INSTANCE_1": {
          "ServiceUri": "YOUR_URI",
          "HealthChecks": false
        },
        "INSTANCE_2": {
          "ServiceUri": "YOUR_URI",
          "HealthChecks": false
        }
      }
    }
  }
}

Mithilfe dieser Konfiguration können Sie eine Verbindung mit den beiden verschiedenen Datenbanken im selben Projekt herstellen:

builder.AddSqlServerClient("INSTANCE_1");
builder.AddSqlServerClient("INSTANCE_2");

Verwenden der MySQL-Komponente

Um die MySQL-Komponente für .NET Aspire zu installieren, verwenden Sie einen Befehl wie den folgenden in Ihren .NET Aspire-Projekten, die Datenzugriff erfordern:

dotnet add package Aspire.MySqlConnector --prerelease

Verwenden Sie alternativ die Verknüpfung Hinzufügen > .NET Aspire-Komponente in Visual Studio, um die Komponente über den NuGet-Paket-Manager zu installieren:

Die Datei Program.cs des Projekts *.AppHost zum Zugreifen auf die Datenbank ähnelt dem PostgreSQL-Beispiel:

var mysqldb = builder.AddMySql("mysql")
                     .AddDatabase("mysqldb")
                     .WithPhpMyAdmin();

var myService = builder.AddProject<Projects.MyService>()
                       .WithReference(mysqldb);

Wie die PostgreSQL-Komponente ermöglicht Ihnen auch die MySQL-Komponente das Erstellen eines Containers für Datenbankverwaltungstools. Im vorherigen Beispiel wird der Lösung PhpMyAdmin hinzugefügt.

Verwenden einer MySQL-Datenbank

Das Muster ist in den Projekten identisch, die MySQL-Zugriff benötigen. In der Datei Program.cs registriert dieser Code die Datenbank:

builder.AddMySqlDataSource("mysqldb");

Sobald die Datenbank im zugreifenden Projekt registriert ist, können Sie jederzeit bei Bedarf mit der Datenquelle interagieren, indem Sie Abhängigkeitsinjektion verwenden:

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);
});

Konfigurieren der MySQL-Komponente

Die MySQL-Komponente unterstützt die gleichen drei Optionen zum Verwalten der Konfiguration.

Verbindungszeichenfolgen

Die Datei appsettings.json kann die Verbindungszeichenfolge für die MySQL-Datenbank enthalten:

{
  "ConnectionStrings": {
    "MySqConnection": "Server=myserver;Database=mysqldb;Uid=myuser;Pwd=mypassword"
  }
}

Anschließend können Sie in Ihrem Projekt eine Verbindung mit der Datenbank mit der Verbindungszeichenfolge herstellen, indem Sie etwa folgenden Code verwenden:

builder.AddMySqlDataSource("MySqConnection");

Konfigurationsanbieter

Der Aspire:MySqlConnector-Schlüssel wird verwendet, um die MySQL-Komponente zu konfigurieren.

{
  "Aspire": {
    "MySqlConnector": {
      "ConnectionString": "Server=myserver;Database=mysqldb;Uid=myuser;Pwd=mypassword",
      "HealthChecks": true,
      "Tracing": false,
      "Metrics": false
    }
  }
}

Inlinekonfigurationen

builder.AddMySqlDataSource("mysqldb", static settings => settings.HealthChecks = false);

Informationen zum Ausführen des Seedings für Ihre Datenbank

Der .NET Aspire-Stapel verwendet Container und profitiert dadurch von konsistenten Umgebungen und einfachen Bereitstellungen. Ein Nachteil ist, dass die Container zustandslos sind. Alle Daten oder Schemas, die einer Datenbank hinzugefügt werden, gehen verloren, wenn der Container zerstört wird. .NET Aspire bietet Möglichkeiten für das Seeding für Ihre Datenbanken mit Daten, wenn die Container erstellt werden.

Verwenden von Volumes und Skripts

Die einfachste Möglichkeit für das Seeding Ihrer Datenbank besteht darin, Volumes und SQL-Skripts zu verwenden. Volumes können Daten für mehrere Container gleichzeitig speichern, bieten eine hohe Leistung und können einfach gesichert oder migriert werden. Die in diesen Volumes gespeicherten Skripts werden beim Erstellen eines Containers ausgeführt. Dabei wird die Datenbank mit Daten aufgefüllt. Das Skript kann eine SQL-Datei sein, die die gewünschten Daten und das gewünschte Schema für Ihre Datenbank enthält.

Wenn Sie beispielsweise über dieses SQL-Skript in einer Datei mit dem Namen postgres-backup.sql im Ordner Service.API/Seed verfügen:

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);

Im App-Host Ihrer Lösung können Sie den Ordner Service.API/Seed an den Ordner /docker-entrypoint-initdb.d des Containers binden. Dabei handelt es sich um einen speziellen Ordner im PostgreSQL-Container, der alle SQL-Skripts ausführt, die beim Erstellen des Containers gefunden werden:

    var catalogDB = builder.AddPostgres("postgres")
      .WithPgAdmin()
      .WithEnvironment("POSTGRES_DB", "backendDB")
      .WithBindMount("../Service.API/Seed", "/docker-entrypoint-initdb.d")
      .AddDatabase("backendDB");

Sie können die SQL-Skripts sogar in Schemaerstellungs- und Datenseedingskripts aufteilen. Wenn sie alle im Ordner Service.API/Seed enthalten sind, werden sie ausgeführt, wenn .NET Aspire die Datenbank erstellt.

Datenseeding mithilfe von Entity Framework Core

Für die Komponenten, die Entity Framework Core unterstützen, können Sie das Seeding für Ihre Datenbank mithilfe der Klasse DbContext und mit Entity Framework Core-Migrationen ausführen. Diese Methode verwendet C#-Code für das Seeding der Datenbank. Diese Seeding sollte jedoch nur während der Entwicklungs- oder Testphase erfolgen, nicht in der Produktion.

// 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();
    }
}

Der obige Code überprüft den Zustand der App-Umgebung. Wenn sie sich in der Entwicklungsphase befindet, ruft der Code die Klasse CatalogContext ab und führt die Methode EnsureCreated aus. Diese Methode erstellt die Datenbank und führt alle ausstehenden Migrationen aus.

Weitere Informationen zum Ausführen des Seedings für die verschiedenen Datenbankkomponenten finden Sie in der Dokumentation zu .NET Aspire.