Aracılığıyla paylaş


Entity Framework Core'da .NET Aspire geçişlerini uygula

.NET .NET Aspire projeler kapsayıcılı mimari kullandığından veritabanları kısa ömürlüdür ve her zaman yeniden oluşturulabilir. Entity Framework Core (EF Core), veritabanı şemaları oluşturmak ve güncelleştirmek için geçişler adlı bir özellik kullanır. Uygulama başlatıldığında veritabanları yeniden oluşturulmuş olduğundan, uygulamanız her başlatıldığında veritabanı şemasını başlatmak için geçişler uygulamanız gerekir. Bu, uygulamanıza başlatma sırasında geçişleri çalıştıran bir geçiş hizmeti projesi kaydedilerek gerçekleştirilir.

Bu öğreticide, uygulama başlatma sırasında .NET Aspire projeleri EF Core geçişleri çalıştıracak şekilde yapılandırmayı öğreneceksiniz.

Önkoşullar

.NET .NET Aspireile çalışmak için aşağıdakilerin yerel olarak yüklenmesi gerekir:

Daha fazla bilgi için bkz. .NET.NET Aspire kurulum ve araçve .NET.NET Aspire SDK.

Başlangıç uygulamasını edinme

Bu öğreticide, EF Core'da .NET Aspire geçişlerinin nasıl uygulanacağını gösteren örnek bir uygulama kullanılmaktadır. örnek uygulamayı kopyalamak için kullanın veya aşağıdaki komutu kullanın:

git clone https://github.com/MicrosoftDocs/aspire-docs-samples/

Örnek uygulama SupportTicketApi klasöründedir. Çözümü Visual Studio veya VS Code'da açın ve devam etmeden önce örnek uygulamayı gözden geçirmek ve çalıştığından emin olmak için biraz bekleyin. Örnek uygulama, temel bir destek bileti API'sidir ve aşağıdaki projeleri içerir:

  • SupportTicketApi.Api: API'yi barındıran ASP.NET Core projesi.
  • SupportTicketApi.AppHost: .NET.NET Aspire uygulama ana bilgisayarını ve yapılandırmasını içerir.
  • SupportTicketApi.Data: EF Core bağlamlarını ve modellerini içerir.
  • SupportTicketApi.ServiceDefaults: Varsayılan hizmet yapılandırmalarını içerir.

Beklendiği gibi çalıştığından emin olmak için uygulamayı çalıştırın. .NET .NET Aspire panosunda tüm kaynaklar çalışana ve iyi durumda olana kadar bekleyin. Ardından https Swagger uç noktasını seçin ve işlemi genişletip Dene'yi seçerek API'nin GET /api/SupportTickets uç noktasını test edin. İsteği göndermek ve yanıtı görüntülemek için Yürüt'ü seçin.

[
  {
    "id": 1,
    "title": "Initial Ticket",
    "description": "Test ticket, please ignore."
  }
]

Swagger uç noktasını ve .NET.NET Aspire panosunu görüntüleyen tarayıcı sekmelerini kapatın ve hata ayıklamayı durdurun.

Geçiş oluşturma

Uygulanacak bazı geçişler oluşturarak başlayın.

  1. Terminal açma (Ctrl+`Visual Studio).

  2. SupportTicketApi\SupportTicketApi.Api geçerli dizin olarak ayarlayın.

  3. Veritabanı şemasının ilk durumunu yakalamak üzere yeni bir geçiş oluşturmak için dotnet ef komut satırı aracını kullanın:

    dotnet ef migrations add InitialCreate --project ..\SupportTicketApi.Data\SupportTicketApi.Data.csproj
    

    Devam etme komutu:

    • EF Core dizininde geçiş komut satırı aracını çalıştırır. dotnet ef, VERITABANı bağlamının kullanıldığı API hizmeti olduğundan bu konumda çalıştırılır.
    • InitialCreateadlı bir geçiş oluşturur.
    • SupportTicketApi.Data projesindeki Migrations klasöründe geçiş oluşturur.
  4. Modeli yeni bir özellik içermesi için değiştirin. SupportTicketApi.Data\Models\SupportTicket.cs açın ve SupportTicket sınıfına yeni bir özellik ekleyin:

    public sealed class SupportTicket
    {
        public int Id { get; set; }
        [Required]
        public string Title { get; set; } = string.Empty;
        [Required]
        public string Description { get; set; } = string.Empty;
        public bool Completed { get; set; }
    }
    
  5. Modeldeki değişiklikleri yakalamak için başka bir yeni geçiş oluşturun:

    dotnet ef migrations add AddCompleted --project ..\SupportTicketApi.Data\SupportTicketApi.Data.csproj
    

Şimdi uygulamanız gereken bazı geçişler var. Ardından, uygulama başlatma sırasında bu geçişleri uygulayan bir geçiş hizmeti oluşturacaksınız.

Geçiş hizmetini oluşturma

Geçişleri başlangıçta çalıştırmak için, geçişleri uygulayan bir hizmet oluşturmanız gerekir.

  1. Çözüme yeni bir Worker Service projesi ekleyin. Visual Studiokullanıyorsanız Çözüm Gezgini'nde çözüme sağ tıklayın ve Add>New Projectöğesini seçin. Worker Serviceseçin, projeyi SupportTicketApi.MigrationService ve hedef .NET 8.0olarak adlandırın. Komut satırını kullanıyorsanız çözüm dizininden aşağıdaki komutları kullanın:

    dotnet new worker -n SupportTicketApi.MigrationService -f "net8.0"
    dotnet sln add SupportTicketApi.MigrationService
    
  2. SupportTicketApi.Data veya komut satırını kullanarak SupportTicketApi.ServiceDefaults projesine SupportTicketApi.MigrationService ve Visual Studio proje başvurularını ekleyin:

    dotnet add SupportTicketApi.MigrationService reference SupportTicketApi.Data
    dotnet add SupportTicketApi.MigrationService reference SupportTicketApi.ServiceDefaults
    
  3. 📦 AspireMicrosoft.EntityFrameworkCore.SqlServer NuGet paketi başvurusunu, SupportTicketApi.MigrationService'i veya komut satırını kullanarak Visual Studio projesine ekleyin.

    cd SupportTicketApi.MigrationService
    dotnet add package Aspire.Microsoft.EntityFrameworkCore.SqlServer -v "9.1.0"
    
  4. Vurgulanan satırları Program.cs projesindeki SupportTicketApi.MigrationService dosyasına ekleyin:

    using SupportTicketApi.Data.Contexts;
    using SupportTicketApi.MigrationService;
    
    var builder = Host.CreateApplicationBuilder(args);
    
    builder.AddServiceDefaults();
    
    builder.Services.AddHostedService<Worker>();
    
    builder.Services.AddOpenTelemetry()
        .WithTracing(tracing => tracing.AddSource(Worker.ActivitySourceName));
    
    builder.AddSqlServerDbContext<TicketContext>("sqldata");
    
    var host = builder.Build();
    host.Run();
    

    Yukarıdaki kodda:

    • AddServiceDefaults uzantısı yöntemi hizmet varsayılanları işlevselliğini ekler.
    • AddOpenTelemetry uzantı yöntemi , OpenTelemetry işlevselliği'ü yapılandırıyor.
    • AddSqlServerDbContext uzantısı yöntemi, TicketContext hizmetini hizmet koleksiyonuna ekler. Bu hizmet, geçişleri çalıştırmak ve veritabanının tohumlarını oluşturmak için kullanılır.
  5. Worker.cs projesindeki SupportTicketApi.MigrationService dosyasının içeriğini aşağıdaki kodla değiştirin:

    using System.Diagnostics;
    
    using Microsoft.EntityFrameworkCore;
    using Microsoft.EntityFrameworkCore.Infrastructure;
    using Microsoft.EntityFrameworkCore.Storage;
    
    using OpenTelemetry.Trace;
    
    using SupportTicketApi.Data.Contexts;
    using SupportTicketApi.Data.Models;
    
    namespace SupportTicketApi.MigrationService;
    
    public class Worker(
        IServiceProvider serviceProvider,
        IHostApplicationLifetime hostApplicationLifetime) : BackgroundService
    {
        public const string ActivitySourceName = "Migrations";
        private static readonly ActivitySource s_activitySource = new(ActivitySourceName);
    
        protected override async Task ExecuteAsync(CancellationToken cancellationToken)
        {
            using var activity = s_activitySource.StartActivity("Migrating database", ActivityKind.Client);
    
            try
            {
                using var scope = serviceProvider.CreateScope();
                var dbContext = scope.ServiceProvider.GetRequiredService<TicketContext>();
    
                await RunMigrationAsync(dbContext, cancellationToken);
                await SeedDataAsync(dbContext, cancellationToken);
            }
            catch (Exception ex)
            {
                activity?.RecordException(ex);
                throw;
            }
    
            hostApplicationLifetime.StopApplication();
        }
    
        private static async Task RunMigrationAsync(TicketContext dbContext, CancellationToken cancellationToken)
        {
            var strategy = dbContext.Database.CreateExecutionStrategy();
            await strategy.ExecuteAsync(async () =>
            {
                // Run migration in a transaction to avoid partial migration if it fails.
                await dbContext.Database.MigrateAsync(cancellationToken);
            });
        }
    
        private static async Task SeedDataAsync(TicketContext dbContext, CancellationToken cancellationToken)
        {
            SupportTicket firstTicket = new()
            {
                Title = "Test Ticket",
                Description = "Default ticket, please ignore!",
                Completed = true
            };
    
            var strategy = dbContext.Database.CreateExecutionStrategy();
            await strategy.ExecuteAsync(async () =>
            {
                // Seed the database
                await using var transaction = await dbContext.Database.BeginTransactionAsync(cancellationToken);
                await dbContext.Tickets.AddAsync(firstTicket, cancellationToken);
                await dbContext.SaveChangesAsync(cancellationToken);
                await transaction.CommitAsync(cancellationToken);
            });
        }
    }
    

    Yukarıdaki kodda:

    • Çalışan başladığında ExecuteAsync yöntemi çağrılır. Sırayla aşağıdaki adımları gerçekleştirir:
      1. Hizmet sağlayıcısından TicketContext hizmetine referans alır.
      2. Bekleyen tüm geçişleri uygulamak için RunMigrationAsync öğesini çağırır.
      3. İlk verilerle veritabanının tohumunu oluşturmak için SeedDataAsync çağırır.
      4. çalışanı StopApplicationile durdurur.
    • RunMigrationAsync ve SeedDataAsync yöntemleri, veritabanıyla etkileşim kurarken oluşabilecek geçici hataları işlemek için yürütme stratejilerini kullanarak ilgili veritabanı işlemlerini kapsüller. Yürütme stratejileri hakkında daha fazla bilgi edinmek için bkz. Bağlantı Dayanıklılığı.

Geçiş hizmetini orkestratöre ekle

Geçiş hizmeti oluşturulur, ancak uygulama başlatıldığında çalışması için .NET.NET Aspire uygulama konağına eklenmesi gerekir.

  1. SupportTicketApi.AppHost projesinde Program.cs dosyasını açın.

  2. ConfigureServices yöntemine aşağıdaki vurgulanmış kodu ekleyin:

    var builder = DistributedApplication.CreateBuilder(args);
    
    var sql = builder.AddSqlServer("sql", port: 14329)
                     .WithEndpoint(name: "sqlEndpoint", targetPort: 14330)
                     .AddDatabase("sqldata");
    
    builder.AddProject<Projects.SupportTicketApi_Api>("api")
        .WithReference(sql)
        .WaitFor(sql);
    
    builder.AddProject<Projects.SupportTicketApi_MigrationService>("migrations")
        .WithReference(sql)
        .WaitFor(sql);
    
    builder.Build().Run();
    

    Bu, SupportTicketApi.MigrationService projesini .NET.NET Aspire uygulama konağına hizmet olarak kaydeder.

  3. Kod geçiş hizmeti projesini çözümleyemiyorsa, AppHost projesinde geçiş hizmeti projesine bir başvuru ekleyin:

    dotnet add SupportTicketApi.AppHost reference SupportTicketApi.MigrationService
    

    Önemli

    Visual Studiokullanıyorsanız ve Enlist in Aspire orchestration projesini oluştururken Worker Service seçeneğini belirlediyseniz, supportticketapi-migrationservicehizmet adıyla benzer kod otomatik olarak eklenir. Bu kodu önceki kodla değiştirin.

Mevcut tohumlama kodunu kaldırma

Geçiş hizmeti veritabanının çekirdeğini oluşturabildiğinden, api projesinden mevcut veri çekirdek oluşturma kodunu kaldırmanız gerekir.

  1. SupportTicketApi.Api projesinde Program.cs dosyasını açın.

  2. Vurgulanan satırları silin.

    if (app.Environment.IsDevelopment())
    {
        app.UseSwagger();
        app.UseSwaggerUI();
    
        using (var scope = app.Services.CreateScope())
        {
            var context = scope.ServiceProvider.GetRequiredService<TicketContext>();
            context.Database.EnsureCreated();
    
            if(!context.Tickets.Any())
            {
                context.Tickets.Add(new SupportTicket { Title = "Initial Ticket", Description = "Test ticket, please ignore." });
                context.SaveChanges();
            }
        }
    }
    

Geçiş hizmetini test edin

Geçiş hizmeti yapılandırıldığına göre, geçişleri test etmek için uygulamayı çalıştırın.

  1. Uygulamayı çalıştırın ve SupportTicketApi panosunu gözlemleyin.

  2. Kısa bir bekleyişten sonra, migrations hizmet durumu Bittiolarak görüntülenir.

    Geçiş hizmeti Tamamlanmış durumda olan .NET.NET Aspire panosunun ekran görüntüsü.

  3. Yürütülen SQL komutlarını gösteren günlükleri araştırmak için geçiş hizmetindeki Console logs simgesini seçin.

Kodu Al

tamamlanmış örnek uygulamasını GitHubadresinde bulabilirsiniz.

Daha fazla örnek kod

Aspire Shop örnek uygulaması, geçişleri uygulamak için bu yaklaşımı kullanır. Geçiş hizmeti uygulaması için AspireShop.CatalogDbManager projesine bakın.