EntityFramework Core ile Çoklu Veritabanı Uygulama ve Migration İşlemleri
Merhabalar, bugünkü yazımda ef core ile bir projede postgresql, sql server ve sqllite gibi birden çok provider’ın ef core içinde nasıl eklenebileceğini yöneteceğiz.
Birden çok context ve veritabanı ayarlaması
Visual studio 2022 ile .net 7.0 web api projesi olarak açıyorum.
Domaine Entites adında klasör açıp, iki tane Entity oluşturuyorum User ve Book olarak.
User ve Book Entityleri:
1 2 3 4 5 6 |
public class User { public int Id { get; set; } public string Name { get; set; } = string.Empty; public DateTime BirthDate { get; set; } } |
1 2 3 4 5 6 7 |
public class Book { public int Id { get; set; } public string Title { get; set; } = string.Empty; public string Author { get; set; } = string.Empty; public DateTime ReleaseDate { get; set; } } |
Data katmanı içine UserContext ve BookContext ekliyoruz.
1 2 3 4 5 6 7 8 9 10 11 12 |
public class UserContext : DbContext { public UserContext(DbContextOptions<UserContext> options) : base(options) { } public DbSet<User> Users { get; set; } = default!; protected override void OnModelCreating(ModelBuilder modelBuilder) { base.OnModelCreating(modelBuilder); modelBuilder.ApplyConfigurationsFromAssembly(typeof(UserContext).Assembly); } } |
1 2 3 4 5 6 |
public class BookContext : DbContext { public BookContext(DbContextOptions<BookContext> contextOptions) : base(contextOptions) { } public DbSet<Book> Books { get; set; } = default!; } |
UserContext SqlServer üzerinde BookContext ise Postgresql veritabanı kullanılacak.
User entitysi için bir optional configuration:
1 2 3 4 5 6 7 |
public class UserEntityTypeConfiguration : IEntityTypeConfiguration<User> { public void Configure(EntityTypeBuilder<User> builder) { builder.Property(p => p.Name).HasMaxLength(100).IsRequired(); } } |
Çoklu Veritabanı Ayarlama
Postgresql için Npgsql provider’ını kullanacağız. Api katmanında yazdığımız Contextleri ayarlarıyla kaydedeceğiz. Önce appSettings.json‘a connection string bilgilerini girelim.
1 2 3 4 |
"ConnectionStrings": { "UserContext": "Server=(localdb)\\mssqllocaldb;Database=UserDb;Trusted_Connection=True;MultipleActiveResultSets=true", "BookContext": "Server=127.0.0.1;Port=5432;Database=BookDb;User Id=postgres;Password=1234567;" } |
Program.cs:
1 2 3 4 5 6 7 8 |
builder.Services.AddDbContext<SqlServerContext>(options => { options.UseSqlServer(builder.Configuration.GetConnectionString("SqlServerContext"), x => x.MigrationsAssembly("EfMultipleProvider.Data")); }); builder.Services.AddDbContext<PostgreContext>(options => { options.UseNpgsql(builder.Configuration.GetConnectionString("PostgreContext")); }); |
Migrationları oluşturma
Projenin kök dizininden powershell ile migrationları oluşturacağız. Oluşturmadan önce kullanacağımız ifadelerin açıklamasını yapalım
–project: Migrationların saklandığı proje
–output-dir: Migrationların oluşacağı klasör yolur
–context : İlgili context
–startup-project: Contextlerin register olduğu proje
UserContext migrationı:
1 |
dotnet ef migrations add UserInitial --context UserContext --output-dir ../Data/UserMigrations --startup-project Api --project Data |
BookContext migrationı
1 |
dotnet ef migrations add BookInitial --context BookContext --output-dir ../Data/BookMigrations --startup-project Api --project Data |
Çalıştırdığımızda Data katmanı içinde aşağıdaki şekilde migrationlar oluşacaktır:
Migrationları Veritabanına Geçirme:
Bunun için iki yol var. İlki update-database ile diğeri uygulama ayağa kalkarken sağlamak.
1.Update-Database ile
1 |
dotnet ef database update --context UserContext --project Data --startup-project Api |
2.Runtime anında
1 2 3 4 5 6 7 8 9 10 11 12 13 |
public static class RunMigrations { public static void ExecuteMigrations(this IServiceCollection services) { using var scope = services.BuildServiceProvider().CreateScope(); var userContext = scope.ServiceProvider.GetRequiredService<UserContext>(); if (userContext.Database.GetPendingMigrations().Any()) userContext.Database.Migrate(); var bookContext = scope.ServiceProvider.GetRequiredService<BookContext>(); if (bookContext.Database.GetPendingMigrations().Any()) bookContext.Database.Migrate(); } } |
1 |
builder.Services.ExecuteMigrations(); |
Örnek bir insert işlemi:
1 2 3 4 5 6 |
app.MapGet("/user-insert", (UserContext context) => { context.Users.Add(new User { Name = "Banu" }); context.SaveChanges(); return Results.Ok(); }); |
Proje Github linki: okankrdg/EfCoreMultipleProvider (github.com)
Bir sonraki yazıda görüşmek üzere, sevgilerle