3 min read

Entity Framework Core ile Seeding

Bu yazıda Entity Framework Core ile bir veritabanı ilk oluşturulduğunda veri ekleme yani seeding işlemini uygulayacağız.
Entity Framework Core ile Seeding

Entity Framework Core ile veritabanına ilk oluşturma esnasında veri eklemek yani seeding yapmak mümkün. Migration kullanmadığımız durumda EnsureCreated() metodu ile veritabanını oluşturabiliyoruz. Bu metot aynı zamanda veritabanını oluşturduktan hemen sonra HasData() ile belirttiğimiz seed verilerini ilgili tablolara ekler.

Context sınıfında OnModelCreating() metoduna tanımlamayı yapalım.

  • Burada önemli olan bir nokta, normal bir insert işleminde otomatik oluşturuluyor olsa da, primary key yani Id'ler için seed ederken elle birer değer vermemiz gerekiyor. Aksi halde hata alırsınız.
  • Bir diğer püf noktası da bir foreign key varsa buna da yine elle değer vermek gerekli. Örneğin seed edilecek bir Order nesnesi için CustomerId değerini vermezsek bu işlem başarısız olur ve hata ile karşılaşırız.
 protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    base.OnModelCreating(modelBuilder);
    modelBuilder.Entity<Customer>(entity =>
    {
        entity.HasKey(c => c.Id);
        entity.HasData(new Customer { Id = 1, Firstname = "Jack", Lastname = "Sparrow" });
    });

    modelBuilder.Entity<Order>(entity => 
    {
        entity.HasKey(o => o.Id);
        entity.HasOne(o => o.Customer)
            .WithMany(c => c.Orders)
            .HasForeignKey(k => k.CustomerId);
        entity.Property(o => o.DateCreated).HasDefaultValueSql("NOW()");
        entity.HasData(
            new Order { Id = 1, CustomerId = 1, Details = "Sale 1", Total = 19M },
            new Order { Id = 2, CustomerId = 1, Details = "Sale 2", Total = 9.99M });
    });
}

Controller içerisinde EnsureCreated() ile veritabanının -eğer yoksa- oluşmasını sağlayalım.

[HttpGet]
public IList<Customer> Get()
{   
    _context.Database.EnsureCreated();                    
    return _context.Customer.Include(c => c.Orders).ToList();
}

Swagger arayüzünden Http GET isteği yaptığımızda seed edilen verilerin veritabanına kaydedilmiş olduğunu görebiliriz.

Seed işlemi için ayrı metot yazılması

Eğer seed işlemini OnModelCreating() metodundan ayrı bir yerde tutmak istiyorsanız bu kısmı bir extension metodu yazarak o şekilde çağırabilirsiniz.

Örneğin aşağıdaki sınıfın Seed() metodu yukarıdaki Fluent API tanımındaki seed kısmının ayrılmış halidir.

public static class ModelBuilderExtensions
{
    public static void Seed(this ModelBuilder modelBuilder)
    {
    	modelBuilder.Entity<Customer>(entity =>
        {               
         	entity.HasData(new Customer { Id = 1, Firstname = "Jack", Lastname = "Sparrow" });
        });

        modelBuilder.Entity<Order>(entity => {              
        	entity.HasData(
            	new Order { Id = 1, CustomerId = 1, Details = "Sale 1", Total = 19M },
                new Order { Id = 2, CustomerId = 1, Details = "Sale 2", Total = 9.99M });
        });
     }
}

Bu metodu artık OnModelCreating() içerisinde çağırabiliriz.

 protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    base.OnModelCreating(modelBuilder);
    modelBuilder.Entity<Customer>(entity => entity.HasKey(c => c.Id));

    modelBuilder.Entity<Order>(entity => 
    {
        entity.HasKey(o => o.Id);
        entity.HasOne(o => o.Customer)
            .WithMany(c => c.Orders)
            .HasForeignKey(k => k.CustomerId);
        entity.Property(o => o.DateCreated).HasDefaultValueSql("NOW()");     
    });
    //custom extension method for seeding data
    modelBuilder.Seed();
}

Swagger arayüzünden yine Http GET isteği sonucunda seed verisinin eklendiğini görebiliyoruz.

Son söz.

Bu yazıda Entity Framework Core ile seeding yaparak veritabanı oluştuğu anda hemen içerisine bazı verilerin eklenmesini sağladık. Seeding ile etiket, kategori, şehir-ülke gibi çok kullanılan ama pek de değişmeyen verilerin veritabanına daha başlangıçtan yazılması büyük kolaylık sağlar. Seeding'i test amaçlı da kullanabilirsiniz. Kullanıcılar, siparişler, ürünler gibi verileri (belki fake data üretici kütüphaneler de kullanarak) seed edebilirsiniz. Böylece veritabanını sanki uzun süredir kullanılıyormuş gibi gerçekçi verilerle doldurup testlerinizde kolaylık sağlayabilirsiniz. Bir sonraki yazıda görüşmek üzere, hoşçakalın.