Entity Framework – Code First OnModelCreating Metodu

Merhaba,

Entity Framework – Code First yapısına önceki yazılarımızda giriş yapmıştık. Önceki yazılara göz atmak için Entity Framework isimli kategoriye gitmeniz yeterlidir. Bu yazımızda ise Code First yaklaşımında DbContext üzerinden gelen OnModelCreating metodunu inceleyeceğiz.

OnModelCreating Metodu Nasıl Çalışır? Ne İşlev Görmektedir?
OnModelCreating metodu, veritabanı ilk defa oluşturulurken tetiklenen bir virtual metotdur. DbContext içerisinde bulunur. Code First yapısında DbContext’ten miras alarak oluşturduğumuz Context sınıfımızda override ederek kullanacağız. Bu metod sayesinde veritabanı tabloları oluşturulmadan araya girecek, tablo isimlerine müdahale edebilecek veya kolonlara istediğimiz ayarları gerçekleştirebileceğiz.

Şimdi aşağıdaki kod bloğunu inceleyiniz.

    class OkulDBContext : DbContext
    {
        public DbSet<Ogrenci> Ogrenciler { get; set; }
        public DbSet<Ogretmen> Ogretmenler { get; set; }
        public DbSet<Memur> Memurlar { get; set; }
    }

Bu şekilde bir Context’i çalıştırıp, veritabanını oluşturduğumuz zaman tablolarda aşağıdaki gibi bir isimlendirmeyle karşılaşıyoruz.

Entity Framework - Code First OnModelCreating Metodu

Entity Framework – Code First OnModelCreating Metodu

Gördüğünüz gibi oluşturmak istediğim tabloların isimlerinin sonuna ‘s’ takısı koyulmakta, bu şekilde anlamsız bir veritabanı dizaynıyla karşılaşılmaktadır.

Tablo Adını Ayarlama

OnModelCreating metodu ile tablolar oluşturulmadan araya girerek aşağıdaki gibi tablo isimlerini belirleyebiliyoruz.

    class OkulDBContext : DbContext
    {
        public DbSet<Ogrenci> Ogrenciler { get; set; }
        public DbSet<Ogretmen> Ogretmenler { get; set; }
        public DbSet<Memur> Memurlar { get; set; }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Ogrenci>().ToTable("Ogrenciler");
            modelBuilder.Entity<Ogretmen>().ToTable("Ogretmenler");
            modelBuilder.Entity<Memur>().ToTable("Memurlar");
        }
    }

Bu şekilde alınan sonuç aşağıdaki gibidir.

Entity Framework - Code First OnModelCreating Metodu

Entity Framework – Code First OnModelCreating Metodu

ToTable metodunun aşağıdaki gibi ikinci parametresinide kullanırsak eğer oluşturulacak tablonun varsayılan(dbo) şeması yerine verilen değeri şema olarak belirtebilirsiniz.

    class OkulDBContext : DbContext
    {
        public DbSet<Ogrenci> Ogrenciler { get; set; }
        public DbSet<Ogretmen> Ogretmenler { get; set; }
        public DbSet<Memur> Memurlar { get; set; }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Ogrenci>().ToTable("Ogrenciler", "okul");
            modelBuilder.Entity<Ogretmen>().ToTable("Ogretmenler", "okul");
            modelBuilder.Entity<Memur>().ToTable("Memurlar", "okul");
        }
    }
Entity Framework - Code First OnModelCreating Metodu

Entity Framework – Code First OnModelCreating Metodu

Kolon Özelliklerini Ayarlama

Tablolar oluşturulmadan nasıl araya girerek tablo adını ayarladıysak, aynı mantıkla kolonlar içinde ayarlama gerçekleştirebiliriz.

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
          ...
            modelBuilder.Entity<Ogrenci>().Property(p => p.Adi)
                .HasColumnName("Adi")
                .HasColumnOrder(2)
                .HasMaxLength(30);
          ...
        }

Yukarıdaki örnek kod bloğunu incelerseniz eğer sadece Ogrenci tablosuna örneklendirme yapılmıştır. Örnek amaçlı “Adi” kolunu seçilmiş ve “HasColumnName” metodu ile adını, “HasColumnOrder” metodu ile sıralamasını ve “HasMaxLength” metodu ile de karakter sayısını belirtmiş oldum. Tabi burada örneklendirme amaçlı sınırlı metodlar seçilmiştir. Siz kurcalayarak daha geniş bilgi edinebilirsiniz.

Entity Framework - Code First OnModelCreating Metodu

Entity Framework – Code First OnModelCreating Metodu

Bu yazımızında sonuna gelmiş bulunmaktayız.
Zahmet edip, okuduğunuz için teşekkür ederim…

Sonraki yazılarımda görüşmek üzere…
İyi çalışmalar…

Bunlar da hoşunuza gidebilir...

4 Cevaplar

  1. Samet Can Karataş dedi ki:

    bu metodun her seferinde çalışanı var mı hocam? Örneğin her Products tablosu çağrılacağında dinamik bir şema adıyla çağırmak istiyorum fakat sadece uygulamayı ilk çalıştırdığımda verdiğim şema çalışıyor ikinci şema ise çalışmıyor eski şema kalıyor.

    Kod

    public readonly string SchemaName;
    public LastTokenTestWithSchemaDbContext(ICompanyProvider _companyProvider, DbContextOptions options) : base(options)
            {
                SchemaName = _companyProvider.GetSchemaName();
            }
    
            public DbSet Products { get; set; }
    
    
            protected override void OnModelCreating(ModelBuilder modelBuilder)
            {
                modelBuilder.Entity().ToTable("products", SchemaName);
                //modelBuilder.HasDefaultSchema(SchemaName);
                base.OnModelCreating(modelBuilder);
            }
    
    • Gençay dedi ki:

      Merhaba,

      Şuradaki kaynağı incelemenizi ve tavsiye edilen extension metot ile çözümü denemenizi tavsiye ederim.

      Sonuç ne olursa olsun bize dönüş yapmanızı ve çözüme kavuştuğunuz taktirde bizide bilgilendirmenizi rica ederim.

      İyi çalışmalar…

  2. Samet Can Karataş dedi ki:

    Merhaba hocam,
    sorunumu çözüme kavuşturdum fakat farklı bir şekilde.

    DbContext’in içerisi

            public readonly string SchemaName;
            ICompanyProvider companyProvider;
            public LastTokenTestWithSchemaDbContext(ICompanyProvider _companyProvider, DbContextOptions options) : base(options)
            {
                SchemaName = _companyProvider.GetSchemaName();
            }
    
            public DbSet Products { get; set; }
    
            protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
            => optionsBuilder
            .ReplaceService();
    
            protected override void OnModelCreating(ModelBuilder modelBuilder)
            {
                modelBuilder.HasDefaultSchema(SchemaName);
                base.OnModelCreating(modelBuilder);
            }
    

    OnConfigure içerisinde kullandığım MultiTenant dosyalarının içerisi

            public class MultiTenantModelCacheKey : ModelCacheKey
            {
                private readonly string _schemaName;
                public MultiTenantModelCacheKey(string schemaName, DbContext context) : base(context)
                {
                    _schemaName = schemaName;
                }
                public override int GetHashCode()
                {
                    return _schemaName.GetHashCode();
                }
            }
    
            public class MultiTenantModelCacheKeyFactory : ModelCacheKeyFactory
            {
                public MultiTenantModelCacheKeyFactory(ModelCacheKeyFactoryDependencies dependencies) : base(dependencies)
                {
                }
                private string _schemaName;
                public override object Create(DbContext context)
                {
                    var dataContext = context as LastTokenTestWithSchemaDbContext;
                    if (dataContext != null)
                    {
                        _schemaName = dataContext.SchemaName;
                    }
                    return new MultiTenantModelCacheKey(_schemaName, context);
                }
            }
    

    ve son olarak multitenant’ı service’e ekliyorum.

    services.AddTransient<IModelCacheKeyFactory, MultiTenantModelCacheKeyFactory>());
    

    Bu işlemler sonucunda OnConfigure her dbcontext çalıştığınında çalışıyor ve multitenant sayesinde schemaname’i değiştirerek farklı şema girişini sağlıyor.

    İyi çalışmalar dilerim.

Bir cevap yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

*