Övning – Använda databastjänster för att spara data från ett .NET Aspire-projekt
I den här övningen ersätter du de aktuella datalagren för företagets molnbaserade app under utveckling. För närvarande använder appen en lokalt lagrad SQLite-databas för katalogdata och en minnesintern Redis-cache för kundens kundkorgar. Du ersätter befintliga datalager med PostgreSQL och MongoDB.
Installera förutsättningar
Förutsättningarna för .NET Aspire är:
- .NET 8
- Förhandsversion av Visual Studio 2022
- Docker Desktop eller Podman
- .NET Aspire-arbetsbelastning i Visual Studio
Om du redan har installerat förhandskraven kan du gå vidare till kloning av den befintliga appen.
Installera .NET 8
Följ den här länken .NET 8 och välj rätt installationsprogram för operativsystemet. Om du till exempel använder Windows 11 och en modern processor väljer du X64 .NET 8 SDK för Windows.
När nedladdningen är klar kör du installationsprogrammet och följer anvisningarna. I ett terminalfönster kör du följande kommando för att kontrollera att installationen lyckades:
dotnet --version
Du bör se versionsnumret för .NET SDK som du har installerat. Till exempel:
8.0.300-preview.24203.14
Installera Visual Studio 2022 Preview
Följ den här länken Visual Studio 2022 Preview och välj Hämta förhandsversion. När nedladdningen är klar kör du installationsprogrammet och följer anvisningarna.
Installera Docker Desktop
Följ den här länken Docker Desktop och välj rätt installationsprogram för operativsystemet. När nedladdningen är klar kör du installationsprogrammet och följer anvisningarna.
Öppna Docker Desktop-programmet och godkänn tjänstavtalet.
Installera .NET Aspire-arbetsbelastningen i Visual Studio
Installera .NET Aspire-arbetsbelastningen med .NET CLI:
Öppna en terminal.
Installera .NET Aspire-arbetsbelastningarna med följande kommandon:
dotnet workload update dotnet workload install aspire dotnet workload list
Du bör se information om .NET Aspire-arbetsbelastningen.
Installed Workload Id Manifest Version Installation Source --------------------------------------------------------------------------------------------- aspire 8.0.0/8.0.100 SDK 8.0.300-preview.24203, VS 17.10.34902.84 Use `dotnet workload search` to find additional workloads to install.
Klona och ändra appen Northern Mountains
Vi använder git
för att hämta den aktuella northern mountains-appen:
På kommandoraden bläddrar du till en mapp där du kan arbeta med kod.
Kör följande kommando för att klona Northern Mountains eShop exempelprogram:
git clone -b aspire-databases https://github.com/MicrosoftDocs/mslearn-aspire-starter
Starta Visual Studio och välj sedan Öppna ett projekt eller en lösning.
Bläddra till mappen där du klonade eShop, öppna mappen start och välj filen eShop.databases.sln, och välj sedan Öppna.
I Solution Explorerexpanderar du projektet eShop.AppHost och öppnar sedan Program.cs.
// Databases var basketStore = builder.AddRedis("BasketStore").WithRedisCommander(); // Identity Providers var idp = builder.AddKeycloakContainer("idp", tag: "23.0") .ImportRealms("../Keycloak/data/import"); // DB Manager Apps builder.AddProject<Projects.Catalog_Data_Manager>("catalog-db-mgr"); // API Apps var catalogApi = builder.AddProject<Projects.Catalog_API>("catalog-api"); var basketApi = builder.AddProject<Projects.Basket_API>("basket-api") .WithReference(basketStore) .WithReference(idp); // Apps // Force HTTPS profile for web app (required for OIDC operations) var webApp = builder.AddProject<Projects.WebApp>("webapp") .WithReference(catalogApi) .WithReference(basketApi) .WithReference(idp, env: "Identity__ClientSecret");
Föregående kod visar den aktuella konfigurationen för appen. Appen använder en Redis-cache för korgbutiken.
Utforska resten av appen, fokusera på projekten Catalog.Data.Manager och Catalog.API och se hur de använder en lokalt lagrad SQLite-databas.
Starta appen genom att trycka på F5 eller välja Felsökning > Starta felsökning.
Om dialogrutan Starta Docker Desktop visas väljer du Ja.
När instrumentpanelen för eShop .NET Aspire visas, väljer du den säkra slutpunkten för resursen i webbappen.
Appen öppnas i en webbläsare. Du kan utforska appen och se hur den fungerar.
Testanvändarens autentiseringsuppgifter är test@example.com och P@$$w 0rd1.
Om du vill sluta felsöka trycker du på Skift+F5eller väljer Felsökning > Sluta felsöka.
Lägga till en .NET Aspire PostgreSQL-komponent
Teamet som ansvarar för katalogmikrotjänsterna skapade appen för att använda en lokalt lagrad SQLite-databas. Den här metoden passar bra för utveckling, men teamet vill använda en mer robust databas för produktion.
Två projekt ansluter till SQLite-databasen, Catalog.Data.Manager och Catalog.API projekt. Datahanteraren används bara för att skicka data till databasen, så du bör fokusera på projektet Catalog.API.
I Solution Explorerhögerklickar du på projektet Catalog.API och väljer Lägg till>.NET Aspire-paket.
I rutan Sök lägger du till Npgsql.EntityFramework i slutet och trycker på Retur.
I resultatet till vänster väljer du Aspire.Npgsql.EntityFrameworkCore.PostgreSQL.
Till höger väljer du listrutan version och väljer sedan den senaste versionen 8.0.0.
Välj Installera.
Om dialogrutan Förhandsgranska ändringar visas väljer du Använd.
I dialogrutan Licensgodkännande väljer du Jag accepterar.
I Solution Explorerväljer du projektet Catalog.API för att visa innehållet i filen Catalog.API.csproj.
Ta bort
PackageReference
för Microsoft.EntityFrameworkCore.Sqlite:<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="8.0.3" />
Registrera den nya PostgreSQL DbContext
I Solution Explorerexpanderar du projektet Catalog.API och öppnar sedan filen Program.cs.
Ersätt SQLite DbContext:
builder.Services.AddDbContext<CatalogDbContext>( options => options.UseSqlite(builder.Configuration.GetConnectionString("sqlconnection") ?? throw new InvalidOperationException( "Connection string 'sqlconnection' not found.")));
Med den nya PostgreSQL DbContext:
builder.AddNpgsqlDbContext<CatalogDbContext>("CatalogDB");
Appen behöver inte längre läsa Database.db-filen, så ta bort de associerade strängarna i appsettings.json.
I Solution Explorerväljer du appsettings.jsonunder Catalog.API.
Ta bort
ConnectionStrings
-posterna, nu ser filen ut så här:{ "Logging": { "LogLevel": { "Default": "Information", "Microsoft.AspNetCore": "Warning" } }, "OpenApi": { "Endpoint": { "Name": "Catalog.API v1" }, "Document": { "Description": "The Catalog Microservice HTTP API. This is a Data-Driven/CRUD microservice sample", "Title": "eShop - Catalog HTTP API", "Version": "v1" } }, "CatalogOptions": { "PicBasePathFormat": "items/{0}/pic/" } }
Högerklicka på projektet Catalog.Data.Manager och välj sedan Ta bort.
I dialogrutan väljer du OK.
Databasteamet skapar en PostgreSQL-databassäkerhetskopia som du kan använda för att skapa och seeda katalogdatabasen. Du kan visa säkerhetskopian i mappen Catalog.API/Seed.
Seeda PostgreSQL-databasen med hjälp av en bunden volym
Projektet AppHost kan skapa en PostgreSQL-databascontainer, skicka data från en bunden volym och sedan skicka referenser via beroendeinmatning till Catalog.API.
I Solution Explorerhögerklickar du på projektet eShop.AppHost och väljer Lägg till>.NET Aspire-paket.
I rutan Search lägger du till PostgreSQL- i slutet och trycker på Retur.
I resultatet till vänster väljer du Aspire.Hosting.PostgreSQL.
Till höger väljer du listrutan version och väljer sedan den senaste versionen 8.0.0.
Välj Installera.
Om dialogrutan Förhandsgranska ändringar visas väljer du Använd.
I dialogrutan Licensgodkännande väljer du Jag accepterar.
I Solution Explorerexpanderar du projektet eShop.AppHost och öppnar sedan filen Program.cs.
Under kommentaren
//Databases
lägger du till följande kod:// Databases var basketStore = builder.AddRedis("BasketStore").WithRedisCommander(); var postgres = builder.AddPostgres("postgres") .WithEnvironment("POSTGRES_DB", "CatalogDB") .WithBindMount("../Catalog.API/Seed", "/docker-entrypoint-initdb.d").WithPgAdmin(); var catalogDB = postgres.AddDatabase("CatalogDB");
Föregående kod skapar en PostgreSQL-databascontainer, lägger till en databas med namnet CatalogDBoch binder katalogen /docker-entrypoint-initdb.d till .. /Catalog.API/Seed-katalog. Koden skapar också en container för pgAdmin-verktyget som gör att du kan hantera PostgreSQL-databasen.
Skicka
catalogDB
-referensen till projektet Catalog.API genom att lägga till.WithReference(catalogDB)
, koden är nu:// API Apps var catalogApi = builder.AddProject<Projects.Catalog_API>("catalog-api") .WithReference(catalogDB);
Projektet Catalog.Data.Manager behövs inte längre, så ta bort projektet från AppHost-. Ta bort den här koden:
// DB Manager Apps builder.AddProject<Projects.Catalog_Data_Manager>("catalog-db-mgr");
Testa appen
Med hjälp av .NET Aspire kunde ditt team ta bort ett helt projekt. Katalog-API:et behöver dessutom bara en enda kodrad för att lägga till PostgresSQL-databaskontexten. Beroendeinmatning och tjänstidentifiering från AppHost innebär att inga andra kodändringar behövs för att API:et ska kunna ansluta till den nya databasen.
Kompilera och starta appen, tryck på F5eller välj Felsök > Starta felsökning.
Det finns två nya containrar på instrumentpanelen som är värd för PostgreSQL-databasservern och pgAdmin-verktyget. Det finns också en PostgreSQL-databasresurs som är värd för CatalogDB-databasen.
Använd pgAdmin för att ansluta till PostgreSQL-databasen och utforska data. Välj postgres pgadmin slutpunkt.
Expandera Aspire-instanser>postgres>databaser>CatalogDB>Schemas>katalog>tabeller. Högerklicka sedan på tabellen Catalog och välj Visa/Redigera Data>Första 100 Raderna.
Du kan se de data som läses in av AppHost.
Välj fliken eShop-resurser flik i webbläsaren och välj sedan webbappens slutpunkt.
Appen öppnas och fungerar som tidigare.
Om du vill sluta felsöka trycker du på Skift+F5eller väljer Felsökning > Sluta felsöka.
Lägg till .NET Aspire MongoDB-komponenten i appen
Den aktuella appen använder Redis som ett minnesinternt datalager för en kunds varukorg. Teamet vill använda ett mer robust och hållbart datalager för korgen. Ersätt Redis-cachen med en MongoDB-databas.
Ändra Basket.API till att använda MongoDB
- I Solution Explorerhögerklickar du på projektet Basket.API, väljer Lägg tilloch väljer sedan Lägg till>.NET Aspire-paket.
- I rutan Sök anger du MongoDB i slutet och trycker på Retur.
- Välj Aspire.MongoDB.Driveroch välj sedan den senaste 8.0.0 version.
- Välj Installera.
- Om dialogrutan Förhandsgranska ändringar visas väljer du Använd.
- I dialogrutan Licensgodkännande väljer du Jag accepterar. @
Skapa ett MongoDB-korglager
Korgmikrotjänsten använder HostingExtensions
för att hantera Redis-datalagret. Ersätt Redis-datalagret med ett MongoDB-datalager.
I Solution Explorerexpanderar du projektet Basket.API, sedan mappen Storage och väljer sedan filen RedisBasketStore.cs.
Det finns två asynkrona metoder,
GetBasketAsync
ochUpdateBasketAsync
, som använder Redis-cachen. Låt oss skapa MongoDB-versioner av dessa metoder.I Solution Explorerhögerklickar du på mappen Storage och väljer sedan Lägg till>klass.
I dialogrutan Lägg till nytt objekt namnger du filen MongoBasketStore.csoch väljer sedan Lägg till.
Ersätt koden i filen MongoBasketStore.cs med följande kod:
using eShop.Basket.API.Models; using MongoDB.Driver; using MongoDB.Driver.Linq; namespace eShop.Basket.API.Storage; public class MongoBasketStore { private readonly IMongoCollection<CustomerBasket> _basketCollection; public MongoBasketStore(IMongoClient mongoClient) { // The database name needs to match the created database in the AppHost _basketCollection = mongoClient.GetDatabase("BasketDB").GetCollection<CustomerBasket>("basketitems"); } public async Task<CustomerBasket?> GetBasketAsync(string customerId) { var filter = Builders<CustomerBasket>.Filter.Eq(r => r.BuyerId, customerId); return await _basketCollection.Find(filter).FirstOrDefaultAsync(); } public async Task<CustomerBasket?> UpdateBasketAsync(CustomerBasket basket) { var filter = Builders<CustomerBasket>.Filter.Eq(r => r.BuyerId, basket.BuyerId); var result = await _basketCollection.ReplaceOneAsync(filter, basket, new ReplaceOptions { IsUpsert = true }); return result.IsModifiedCountAvailable ? basket : null; } }
Föregående kod skapar en
MongoBasketStore
-klass som fungerar medCustomerBasket
-modellen. Samlingen hanterar CRUD-åtgärderna för kundernas kundkorgar i en MongoDB-databas.I Solution Explorerexpanderar du Basket.API>Extensions och väljer sedan filen HostingExtensions.cs.
Ersätt Redis-koden:
builder.AddRedis("BasketStore"); builder.Services.AddSingleton<RedisBasketStore>();
Med MongoDB-koden:
builder.AddMongoDBClient("BasketDB"); builder.Services.AddSingleton<MongoBasketStore>();
I Solution Explorerexpanderar du mappen Grpc och öppnar sedan filen BasketService.cs.
Ändra klassen så att den accepterar en
MongoBasketStore
, ersätt:public class BasketService(RedisBasketStore basketStore) : Basket.BasketBase
Med:
public class BasketService(MongoBasketStore basketStore) : Basket.BasketBase
Lägga till en MongoDB-databas i AppHost
I Solution Explorerhögerklickar du på projektet eShop.AppHost och väljer Lägg till>.NET Aspire-paket.
I rutan Sök skriver du MongoDB i slutet och trycker på Enter.
Välj paketet Aspire.Hosting.MongoDB och välj sedan den senaste version 8.0.0.
Välj Installera.
Om dialogrutan Förhandsgranska ändringar visas väljer du Använd.
I dialogrutan Licensgodkännande väljer du Jag accepterar. @
I Solution Explorerexpanderar du projektet eShop.AppHost och öppnar sedan filen Program.cs.
I avsnittet Databaser lägger du till en MongoDB-komponent:
var mongo = builder.AddMongoDB("mongo") .WithMongoExpress() .AddDatabase("BasketDB");
Den tidigare koden skapar en MongoDB-databascontainer, lägger till en databas med namnet BasketDB. Koden skapar också en container för Mongo Express-verktyget som gör att du kan hantera MongoDB-databasen.
Ta bort Redis-containern:
var basketStore = builder.AddRedis("BasketStore").WithRedisCommander();
Koden bör nu se ut så här:
// Databases var postgres = builder.AddPostgres("postgres") .WithEnvironment("POSTGRES_DB", "CatalogDB") .WithBindMount("../Catalog.API/Seed", "/docker-entrypoint-initdb.d") .WithPgAdmin(); var catalogDB = postgres.AddDatabase("CatalogDB"); var mongo = builder.AddMongoDB("mongo") .WithMongoExpress() .AddDatabase("BasketDB");
Basket.API-projektet behöver en referens till den nya MongoDB-databasen och du bör ta bort Redis-referensen:
var basketApi = builder.AddProject<Projects.Basket_API>("basket-api") .WithReference(mongo) .WithReference(idp);
Projektet Basket.API är nu redo att använda MongoDB-databasen. Nu ska vi testa appen för att se om den fungerar.
Testa appen
Kompilera och starta appen, tryck på F5eller välj Felsök > Starta felsökning.
Du kan se de nya MongoDB-containrarna, en för databasservern den andra för Mongo Express, på instrumentpanelen. Det finns också en ny MongoDBDatabase resurs som är värd för databasen BasketDB.
Välj slutpunkten för webbappen .
Om du vill logga in med testanvändarautentiseringsuppgifterna väljer du användarikonen längst upp till höger. E-postmeddelandet är test@example.com och lösenordet är P@$$w 0rd1.
Välj Adventurer GPS Watch från startsidan.
Välj Lägg till i shoppingväskan, så bör du se ett undantagsmeddelande.
Felsöka appen
Appen utlöser ett undantag när du försöker lägga till ett objekt i varukorgen. Du kan använda instrumentpanelen för att felsöka problemet.
Välj fliken eShop-resurser kontrollpanel i webbläsaren.
Instrumentpanelen visar fel i basket-api och webbapp. Granska loggarna för basket-api.
För resursen basket-api väljer du Viewi kolumnen Logs .
Det finns ett undantag:
System.FormatException: Element '_id' does not match any field or property of class eShop.Basket.API.Models.CustomerBasket.
Välj menyalternativet Resurser och välj sedan mongo-mongoexpress slutpunkt.
I avsnittet Databases väljer du Viewbredvid BasketDB.
I Collectionsväljer du Viewbredvid basketitems.
Dokument som lagras i en MongoDB har ett _id fält. Varje dokument som lagras i en MongoDB-samling måste ha ett unikt _id fält.
Om du vill sluta felsöka trycker du på Skift+F5eller väljer Felsökning > Sluta felsöka.
Granska koden och åtgärda problemet
Nu ska vi titta på CustomerBasket-och se om vi kan hitta problemet.
I Solution Explorerexpanderar du mappen Basket.API>Models och öppnar sedan filen CustomerBasket.cs.
public class CustomerBasket { public required string BuyerId { get; set; } public List<BasketItem> Items { get; set; } = []; }
CustomerBasket-modellen har inte ett fält eller en egenskap som matchar _id fältet. Entitetsramverket försöker mappa fältet _id till CustomerBasket- modell, och det går inte att hitta någon matchning.
Uppdatera
CustomerBasket
-modellen så att den innehåller ett _id fält:public class CustomerBasket { /// <summary> /// MongoDB document identifier /// </summary> public string _id { get; set; } = ""; public required string BuyerId { get; set; } public List<BasketItem> Items { get; set; } = []; }
Testa den åtgärdade appen
Om du vill kompilera och starta appen trycker du på F5eller väljer Felsökning > Starta felsökning.
För -webbappeni kolumnen Slutpunkter högerklickar du på URL:en och väljer sedan Öppna länk i InPrivate-fönstret.
Om du använder ett InPrivate-fönster ser du till att webbläsaren inte använder den föregående sessionscookien för autentisering.
Om du vill logga in med testanvändarautentiseringsuppgifterna väljer du användarikonen längst upp till höger. E-postmeddelandet är test@example.com och lösenordet är P@$$w 0rd1.
Välj Adventurer GPS Watch från startsidan.
Välj Lägg till i shoppingväskan.
Appkorgsfunktionerna i Northern Mountains fungerar nu.
Du har ersatt SQLite-databasen med en PostgreSQL-databas och Redis-cachen med en MongoDB-databas. Du använde .NET Aspire för att hantera databaserna och utforska data i dem, och du använde instrumentpanelen för att felsöka ett problem med appen.