Ćwiczenie — utrwalanie danych z projektu .NET Aspire przy użyciu usług baz danych
W tym ćwiczeniu zastąpisz bieżące magazyny danych dla firmowej aplikacji natywnej dla chmury. W tej chwili aplikacja używa lokalnie przechowywanej bazy danych SQLite na potrzeby danych katalogu i pamięci podręcznej Redis cache w pamięci dla koszyków zakupów klienta. Istniejące magazyny danych zastępują bazy danych PostgreSQL i MongoDB.
Instalacja wymagań wstępnych
Wymagania wstępne dotyczące platformy .NET Aspire są następujące:
- .NET 8
- Visual Studio 2022 (wersja zapoznawcza)
- Docker Desktop lub Podman
- Obciążenie .NET Aspire w programie Visual Studio
Jeśli masz już zainstalowane wymagania wstępne, możesz przejść do klonowania istniejącej aplikacji.
Instalowanie platformy .NET 8
Postępuj zgodnie z tym linkiem platformy .NET 8 i wybierz prawidłowy instalator dla swojego systemu operacyjnego. Jeśli na przykład używasz systemu Windows 11 i nowoczesnego procesora, wybierz zestaw SDK platformy .NET 8 x64 dla systemu Windows.
Po zakończeniu pobierania uruchom instalatora i postępuj zgodnie z instrukcjami. W oknie terminalu uruchom następujące polecenie, aby sprawdzić, czy instalacja zakończyła się pomyślnie:
dotnet --version
Powinien zostać wyświetlony numer wersji zainstalowanego zestawu .NET SDK. Na przykład:
8.0.300-preview.24203.14
Instalowanie programu Visual Studio 2022 (wersja zapoznawcza)
Postępuj zgodnie z tym linkiem programu Visual Studio 2022 (wersja zapoznawcza) i wybierz pozycję Pobierz wersję zapoznawcza. Po zakończeniu pobierania uruchom instalatora i postępuj zgodnie z instrukcjami.
Instalowanie programu Docker Desktop
Postępuj zgodnie z tym linkiem do programu Docker Desktop i wybierz prawidłowy instalator dla swojego systemu operacyjnego. Po zakończeniu pobierania uruchom instalatora i postępuj zgodnie z instrukcjami.
Otwórz aplikację docker Desktop i zaakceptuj umowę serwisową.
Instalowanie obciążenia platformy .NET Aspire w programie Visual Studio
Zainstaluj obciążenie platformy .NET Aspire przy użyciu interfejsu wiersza polecenia platformy .NET:
Otwórz terminal.
Zainstaluj obciążenia platformy .NET Aspire przy użyciu następujących poleceń:
dotnet workload update dotnet workload install aspire dotnet workload list
Powinny zostać wyświetlone szczegóły obciążenia platformy .NET Aspire.
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.
Klonowanie i modyfikowanie aplikacji Góry Północne
Użyjmy polecenia git
, aby uzyskać bieżącą aplikację Gór Północnych:
W wierszu polecenia przejdź do wybranego folderu, w którym możesz pracować z kodem.
Wykonaj następujące polecenie, aby sklonować przykładową aplikację eShop w Górach Północnych:
git clone -b aspire-databases https://github.com/MicrosoftDocs/mslearn-aspire-starter
Uruchom program Visual Studio, a następnie wybierz pozycję Otwórz projekt lub rozwiązanie.
Przejdź do folderu, w którym sklonujesz eShop, otwórz folder Start i wybierz plik eShop.databases.sln , a następnie wybierz pozycję Otwórz.
W Eksplorator rozwiązań rozwiń projekt eShop.AppHost, a następnie otwórz 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");
Poprzedni kod przedstawia bieżącą konfigurację aplikacji. Aplikacja używa pamięci podręcznej Redis dla sklepu koszyka.
Zapoznaj się z resztą aplikacji, skoncentruj się na projektach Catalog.Data.Manager i Catalog.API i zobacz, jak używają lokalnie przechowywanej bazy danych SQLite.
Aby uruchomić aplikację, naciśnij F5 lub wybierz pozycję Debuguj > rozpocznij debugowanie.
Jeśli zostanie wyświetlone okno dialogowe Uruchamianie programu Docker Desktop, wybierz pozycję Tak.
Po wyświetleniu pulpitu nawigacyjnego eShop .NET Aspire dla zasobu aplikacji internetowej wybierz bezpieczny punkt końcowy:
Aplikacja zostanie otwarta w przeglądarce. Możesz eksplorować aplikację i zobaczyć, jak działa.
Poświadczenia użytkownika testowego to test@example.com i P@$$w 0rd1.
Aby zatrzymać debugowanie, naciśnij Shift+F5 lub wybierz pozycję Debuguj zatrzymaj > debugowanie.
Dodawanie składnika .NET Aspire PostgreSQL
Zespół odpowiedzialny za mikrousługi katalogu utworzył aplikację do korzystania z lokalnie przechowywanej bazy danych SQLite. Takie podejście jest odpowiednie do programowania, ale zespół chce użyć bardziej niezawodnej bazy danych do produkcji.
Dwa projekty łączą się z bazą danych SQLite, projektami Catalog.Data.Manager i Catalog.API . Menedżer danych jest używany tylko do rozmieszczania bazy danych z danymi, więc należy skoncentrować się na projekcie Catalog.API .
W Eksplorator rozwiązań kliknij prawym przyciskiem myszy projekt Catalog.API, wybierz pozycję Dodaj.NET> Aspire pakiet.
W polu Wyszukaj dodaj element Npgsql.EntityFramework na końcu i naciśnij Enter.
Po lewej stronie w wynikach wybierz pozycję Aspire.Npgsql.EntityFrameworkCore.PostgreSQL.
Po prawej stronie wybierz listę rozwijaną wersji, a następnie wybierz najnowszą wersję 8.0.0 .
Wybierz Zainstaluj.
Jeśli zostanie wyświetlone okno dialogowe Podgląd zmian, wybierz pozycję Zastosuj.
W oknie dialogowym Akceptacja licencji wybierz pozycję Akceptuję.
W Eksplorator rozwiązań wybierz projekt Catalog.API, aby wyświetlić zawartość pliku Catalog.API.csproj.
Usuń element
PackageReference
dla elementu Microsoft.EntityFrameworkCore.Sqlite:<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="8.0.3" />
Rejestrowanie nowej bazy danych PostgreSQL DbContext
W Eksplorator rozwiązań rozwiń projekt Catalog.API, a następnie otwórz plik Program.cs.
Zastąp element SQLite DbContext:
builder.Services.AddDbContext<CatalogDbContext>( options => options.UseSqlite(builder.Configuration.GetConnectionString("sqlconnection") ?? throw new InvalidOperationException( "Connection string 'sqlconnection' not found.")));
Dzięki nowej bazie danych PostgreSQL DbContext:
builder.AddNpgsqlDbContext<CatalogDbContext>("CatalogDB");
Aplikacja nie musi już odczytywać pliku Database.db , więc usuń skojarzone ciągi w appsettings.json.
W Eksplorator rozwiązań w obszarze Catalog.API wybierz pozycję appsettings.json.
ConnectionStrings
Usuń wpisy, plik wygląda teraz następująco:{ "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/" } }
Kliknij prawym przyciskiem myszy projekt Catalog.Data.Manager , a następnie wybierz polecenie Usuń.
W oknie dialogowym wybierz przycisk OK.
Zespół bazy danych tworzy kopię zapasową bazy danych PostgreSQL, która służy do tworzenia i rozmieszczania bazy danych katalogu. Kopię zapasową można wyświetlić w folderze Catalog.API/Seed .
Rozmieszczanie bazy danych PostgreSQL przy użyciu woluminu powiązanego
Projekt AppHost może utworzyć kontener bazy danych PostgreSQL, zainicjować go z danymi z powiązanego woluminu, a następnie za pomocą iniekcji zależności przekazać odwołania do katalogu.API.
W Eksplorator rozwiązań kliknij prawym przyciskiem myszy projekt eShop.AppHost, wybierz pozycję Dodaj.NET> Aspire pakiet.
W polu Wyszukaj dodaj do końca pozycję PostgreSQL i naciśnij Enter.
Po lewej stronie w wynikach wybierz pozycję Aspire.Hosting.PostgreSQL.
Po prawej stronie wybierz listę rozwijaną wersji, a następnie wybierz najnowszą wersję 8.0.0 .
Wybierz Zainstaluj.
Jeśli zostanie wyświetlone okno dialogowe Podgląd zmian, wybierz pozycję Zastosuj.
W oknie dialogowym Akceptacja licencji wybierz pozycję Akceptuję.
W Eksplorator rozwiązań rozwiń projekt eShop.AppHost, a następnie otwórz plik Program.cs.
W komentarzu
//Databases
dodaj następujący 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");
Poprzedni kod tworzy kontener bazy danych PostgreSQL, dodaje bazę danych o nazwie CatalogDB i tworzy powiązanie katalogu /docker-entrypoint-initdb.d z katalogiem .. /Catalog.API/Seed directory. Kod tworzy również kontener dla narzędzia pgAdmin, który umożliwia zarządzanie bazą danych PostgreSQL.
catalogDB
Przekaż odwołanie do projektu Catalog.API, dodając.WithReference(catalogDB)
kod :// API Apps var catalogApi = builder.AddProject<Projects.Catalog_API>("catalog-api") .WithReference(catalogDB);
Projekt Catalog.Data.Manager nie jest już potrzebny, więc usuń projekt z hosta AppHost. Usuń ten kod:
// DB Manager Apps builder.AddProject<Projects.Catalog_Data_Manager>("catalog-db-mgr");
Testowanie aplikacji
Korzystanie z platformy .NET Aspire umożliwiło zespołowi usunięcie całego projektu. Ponadto interfejs API wykazu wymaga tylko jednego wiersza kodu, aby dodać kontekst bazy danych PostgresSQL. Wstrzykiwanie zależności i odnajdywanie usługi z hosta AppHost oznacza, że nie są potrzebne żadne inne zmiany kodu, aby umożliwić interfejsowi API nawiązywanie połączenia z nową bazą danych.
Skompiluj i uruchom aplikację, naciśnij F5 lub wybierz pozycję Debuguj > rozpocznij debugowanie.
Na pulpicie nawigacyjnym znajdują się dwa nowe kontenery, które hostują serwer bazy danych PostgreSQL i narzędzie pgAdmin. Istnieje również zasób bazy danych PostgreSQL hostujący bazę danych CatalogDB.
Użyj narzędzia pgAdmin , aby nawiązać połączenie z bazą danych PostgreSQL i eksplorować dane. Wybierz punkt końcowy postgres pgadmin.
Rozwiń węzeł Aspiruj>wystąpienia postgres>Database CatalogDB Schemas catalog tables (Tabele wykazu schematów>>bazy danych>CatalogDB).> Następnie kliknij prawym przyciskiem myszy tabelę Wykaz, a następnie wybierz pozycję Wyświetl/Edytuj dane>Pierwsze 100 wierszy.
Dane załadowane przez host AppHost są widoczne.
Wybierz kartę pulpitu nawigacyjnego zasobów eShop w przeglądarce, a następnie wybierz punkt końcowy aplikacji internetowej.
Aplikacja zostanie otwarta i działa tak jak poprzednio.
Aby zatrzymać debugowanie, naciśnij Shift+F5 lub wybierz pozycję Debuguj zatrzymaj > debugowanie.
Dodawanie składnika .NET Aspire MongoDB do aplikacji
Bieżąca aplikacja używa usługi Redis jako magazynu danych w pamięci dla koszyka zakupów klienta. Zespół chce użyć bardziej niezawodnego i trwałego magazynu danych dla koszyka. Zastąp pamięć podręczną Redis bazą danych MongoDB.
Zmienianie interfejsu Basket.API w celu używania bazy danych MongoDB
- W Eksplorator rozwiązań kliknij prawym przyciskiem myszy projekt Basket.API, wybierz pozycję Dodaj, a następnie wybierz pozycję Dodaj.NET> Aspire pakiet.
- W polu Wyszukaj wprowadź ciąg MongoDB na końcu i naciśnij Enter.
- Wybierz sterownik Aspire.MongoDB.Driver, a następnie wybierz najnowszą wersję 8.0.0.
- Wybierz Zainstaluj.
- Jeśli zostanie wyświetlone okno dialogowe Podgląd zmian, wybierz pozycję Zastosuj.
- W oknie dialogowym Akceptacja licencji wybierz pozycję Akceptuję. @
Tworzenie magazynu koszyka bazy danych MongoDB
Mikrousługę koszyka używa HostingExtensions
do zarządzania magazynem danych usługi Redis. Zastąp magazyn danych Redis magazynem danych MongoDB.
W Eksplorator rozwiązań rozwiń projekt Basket.API, a następnie folder Storage, a następnie wybierz plik RedisBasketStore.cs.
Istnieją dwie metody asynchroniczne i
GetBasketAsync
UpdateBasketAsync
, które używają pamięci podręcznej Redis Cache. Umożliwia utworzenie wersji bazy danych MongoDB tych metod.W Eksplorator rozwiązań kliknij prawym przyciskiem myszy folder Storage, a następnie wybierz polecenie Dodaj>klasę.
W oknie dialogowym Dodawanie nowego elementu nadaj plikowi nazwę MongoBasketStore.cs, a następnie wybierz pozycję Dodaj.
Zastąp kod w pliku MongoBasketStore.cs następującym kodem:
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; } }
Poprzedni kod tworzy klasę
MongoBasketStore
, która współpracuje z modelemCustomerBasket
. Kolekcja obsługuje operacje CRUD dla koszyków zakupów klientów w bazie danych MongoDB.W Eksplorator rozwiązań rozwiń węzeł Basket.API>Extensions , a następnie wybierz plik HostingExtensions.cs.
Zastąp kod usługi Redis:
builder.AddRedis("BasketStore"); builder.Services.AddSingleton<RedisBasketStore>();
Za pomocą kodu bazy danych MongoDB:
builder.AddMongoDBClient("BasketDB"); builder.Services.AddSingleton<MongoBasketStore>();
W Eksplorator rozwiązań rozwiń folder Grpc, a następnie otwórz plik BasketService.cs.
Zmień klasę tak, aby akceptowała wartość , zastąp
MongoBasketStore
:public class BasketService(RedisBasketStore basketStore) : Basket.BasketBase
Tym:
public class BasketService(MongoBasketStore basketStore) : Basket.BasketBase
Dodawanie bazy danych MongoDB do hosta AppHost
W Eksplorator rozwiązań kliknij prawym przyciskiem myszy projekt eShop.AppHost, a następnie wybierz pozycję Dodaj.NET> Aspire pakiet.
W polu Wyszukaj wprowadź ciąg MongoDB na końcu i naciśnij Enter.
Wybierz pakiet Aspire.Hosting.MongoDB, a następnie wybierz najnowszą wersję 8.0.0.
Wybierz Zainstaluj.
Jeśli zostanie wyświetlone okno dialogowe Podgląd zmian, wybierz pozycję Zastosuj.
W oknie dialogowym Akceptacja licencji wybierz pozycję Akceptuję. @
W Eksplorator rozwiązań rozwiń projekt eShop.AppHost, a następnie otwórz plik Program.cs.
W sekcji Bazy danych dodaj składnik Bazy danych MongoDB:
var mongo = builder.AddMongoDB("mongo") .WithMongoExpress() .AddDatabase("BasketDB");
Poprzedni kod tworzy kontener bazy danych MongoDB, dodaje bazę danych o nazwie BasketDB. Kod tworzy również kontener dla narzędzia Mongo Express, który umożliwia zarządzanie bazą danych MongoDB.
Usuń kontener Redis:
var basketStore = builder.AddRedis("BasketStore").WithRedisCommander();
Kod powinien teraz wyglądać następująco:
// 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");
Projekt Basket.API wymaga odwołania do nowej bazy danych MongoDB i należy usunąć odwołanie do bazy danych Redis:
var basketApi = builder.AddProject<Projects.Basket_API>("basket-api") .WithReference(mongo) .WithReference(idp);
Projekt Basket.API jest teraz gotowy do użycia bazy danych MongoDB. Przetestujmy aplikację, aby sprawdzić, czy działa.
Testowanie aplikacji
Skompiluj i uruchom aplikację, naciśnij F5 lub wybierz pozycję Debuguj > rozpocznij debugowanie.
Na pulpicie nawigacyjnym można zobaczyć nowe kontenery bazy danych MongoDB— jeden dla serwera bazy danych drugi dla usługi Mongo Express. Istnieje również nowy zasób Bazy danych MongoDBDatabase hostujący bazę danych BasketDB .
Wybierz punkt końcowy aplikacji internetowej.
Aby zalogować się przy użyciu poświadczeń użytkownika testowego, wybierz ikonę użytkownika w prawym górnym rogu. Wiadomość e-mail to test@example.com i hasło to P@$$w 0rd1.
Wybierz zegarek GPS Adventurer ze strony głównej.
Wybierz pozycję Dodaj do torby na zakupy. Powinien zostać wyświetlony wyjątek:
Debugowanie aplikacji
Aplikacja zgłasza wyjątek podczas próby dodania elementu do koszyka zakupów. Możesz użyć pulpitu nawigacyjnego, aby ułatwić debugowanie problemu.
Wybierz kartę pulpitu nawigacyjnego zasobów eShop w przeglądarce.
Na pulpicie nawigacyjnym są wyświetlane błędy w interfejsie api koszyka i aplikacji internetowej. Przejrzyj dzienniki dla koszyka-api.
W przypadku zasobu koszyka-api w kolumnie Dzienniki wybierz pozycję Wyświetl.
Istnieje wyjątek:
System.FormatException: Element '_id' does not match any field or property of class eShop.Basket.API.Models.CustomerBasket.
Wybierz element menu Zasoby, a następnie wybierz punkt końcowy mongo-mongoexpress.
W sekcji Bazy danych obok pozycji KoszykDB wybierz pozycję Widok.
W obszarze Kolekcje obok pozycji koszyki wybierz pozycję Widok.
Dokumenty przechowywane w bazie danych MongoDB mają pole _id . Każdy dokument przechowywany w kolekcji bazy danych MongoDB musi mieć unikatowe pole _id .
Aby zatrzymać debugowanie, naciśnij Shift+F5 lub wybierz pozycję Debuguj zatrzymaj > debugowanie.
Przejrzyj kod i rozwiąż problem
Przyjrzyjmy się zasobowi CustomerBasket i sprawdźmy, czy możemy znaleźć problem.
W Eksplorator rozwiązań rozwiń folder Basket.API>Models, a następnie otwórz plik CustomerBasket.cs.
public class CustomerBasket { public required string BuyerId { get; set; } public List<BasketItem> Items { get; set; } = []; }
Model CustomerBasket nie ma pola ani właściwości zgodnej z polem _id. Platforma Entity Framework próbuje zamapować pole _id na model CustomerBasket i nie może odnaleźć dopasowania.
Zaktualizuj model,
CustomerBasket
aby zawierał pole _id :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; } = []; }
Testowanie stałej aplikacji
Aby skompilować i uruchomić aplikację, naciśnij F5 lub wybierz pozycję Debuguj > rozpocznij debugowanie.
W przypadku aplikacji internetowej w kolumnie Punkty końcowe kliknij prawym przyciskiem myszy adres URL, a następnie wybierz pozycję Otwórz link w oknie InPrivate.
Użycie okna InPrivate gwarantuje, że przeglądarka nie używa poprzedniego pliku cookie sesji do uwierzytelniania.
Aby zalogować się przy użyciu poświadczeń użytkownika testowego, wybierz ikonę użytkownika w prawym górnym rogu. Wiadomość e-mail to test@example.com i hasło to P@$$w 0rd1.
Wybierz zegarek GPS Adventurer ze strony głównej.
Wybierz pozycję Dodaj do torby na zakupy.
Funkcja koszyka aplikacji w Górach Północnych działa teraz.
Baza danych SQLite została pomyślnie zastąpiona bazą danych PostgreSQL i pamięcią podręczną Redis za pomocą bazy danych MongoDB. Użyto platformy .NET Aspire do zarządzania bazami danych i eksplorowania w nich danych oraz użyto pulpitu nawigacyjnego w celu debugowania problemu z aplikacją.