Bu yazımda Entity Framework’ün üç tasarım yaklaşımından ikisi olan “Database First“ ve “Code First” yaklaşımlarını avantajları ve deavantajları ile incelemeye ve anlamaya çalışacağız. Bir projeye başlarken; projenin kapsamı, sıfırdan tasarlanacak bir proje mi yoksa bir bakım projesi mi olduğu, zaman ve kaynaklar, ekibin donanımı nasıl bir yaklaşımla projemizi geliştirmemiz gerektiği konusunda bizlere yön vermektedir. Fakat bazen de tabularımız seçimlerimizi etkilemekte ve en iyi bildiğimiz yol doğru yoldur diyerek objektif ve bilimsel bakışı bir kenara bırakmış, kendini tekrar eden bireylere dönüşmekteyiz.
Günümüz teknoloji dünyasında teknolojiden kopmamanın yolu, yeni gelişmeler ışığında kendimizi geliştirmemiz, eğitimler almamız, arge çalışmaları ile paralel şekilde yeni yaklaşımları uygulayabilmemiz ve projelerimizde kullanabilmemiz olacaktır.
Sözü fazla uzatmadan, kendine has kolaylıkları ve zorlukları olan “Database First“ ve “Code First” yaklaşımlarını incelemeye başlayalım.
Code First
Yeni bir projeye başladık ve yaptığımız analizler sonucunda domaini anlamış, uygulama ve geliştirme aşamasına geçebilecek durumda olduğumuzu farz edelim. Bu aşamada “Code First” yaklaşımı ile projemizi geliştirmeye karar veriyoruz. Çözüm geliştireceğimiz domaini birbiriyle ilişkili sınıflar yaratıp tanımlayarak projemize başlıyoruz. Bu sınıflara entitiler de diyebiliriz. Görsel bir modelimiz, bir .edmx dosyamız artık olmayacak. Mevcut veritabanımız olsa bile, sınıflar aracılığı ile mevcut veritabanımızı ve özelliklerini kodlayacağız. Sadece kod yazarak modelimizi tanımlayacağız.
Entitilerimizin veritabanındaki ilişkilerini, özelliklerini ve zorunluluklarımızı kolayca tanımlayabilmek için “Fluent Api” mapping kullanacağız.
“Code First” yaklaşımı ile veritabanınızdaki tablonuza yeni bir kolon eklemek için sadece sınıfınıza yeni bir özellik eklemeniz yeterli olacaktır. Tabi birazdan örneklerini vereceğim “Fluent API” kullanarak mapping tanımlamanızı yapabilirsiniz. Yapmasanız yine de entity framework eklediğiniz özelliği tablonuza dafault seçimleri kullanarak ekleyecektir. Özelleştirmek isterseniz basitçe “Fluent API” ile bunu gerçekleştirebilirsiniz. “Code First” yaklaşımı ile yaptığınız tüm değişiklikler “Migration” sınıflarında tarihçe olarak tutulmaktadır. Tüm veritabanı değişikliklerini sırasıyla bu sınıflar aracılığı ile görebilirsiniz. Yazımızın devamında “Migration” sınıflarına değineceğiz.
Artık projemizi oluşturmaya başlayalım. İlk olarak Visual Studio’larımızı açarak yeni bir console uygulaması yaratıyoruz. Sonrasında Nuget Manager aracılığı ile Entity Framework’ü projemize ekliyoruz. Bu aşamadan sonra projemizin entity sınıflarını projemize ekleyebiliriz.
Gundem Entity Sınıfı:
Issue Entity Sınıfı:
Yazar Entity Sınıfı:
Base Entity Sınıfı:
Entity sınıflarımızı oluşturduk ve bu sınıfların veritabanında ki ilişkilerini istediğimiz gibi özelleştirmek için yazımızın önceki kısımlarında da bahsettiğimiz “Fluent Api” mapping kullanacağız.
Her entity için bir mapping dosyası oluşturarak her bir varlığın veritabanında nasıl oluşmasını istediğimizi ve birbirleriyle ilişkilerinin ne şekilde olacağını belirleyelim. Kontrol tamamen bizde:
Gundem Entity Mapping Sınıfı:
Issue Entity Mapping Sınıfı:
Yazar Entity Mapping Sınıfı:
Entity mapping sınıflarımızı “EntityTypeConfiguration” sınıfından türetmemiz gerekiyor. Entity mapping sınıfımızın constructor metodunda varlığımızın veritabanında nasıl olacağını belirliyoruz.
İlk olarak tablo ismimizi belirliyoruz.
Sonrasında tabloda ki kolonlarımızı tanımlıyoruz. Aşağıdaki örnekte kolon adımız “ADI” ve zorunlu bir alan.
One-To-Many bir ilişki tanımlamak için aşağıdaki örneği kullanıyoruz. Foreign Key olarak kullanılacak “GUNDEM_ID” nin Issue için zorunlu olduğunu belirtiyoruz.
“GUNDEM_ID” ye “IX_ISSUE_GUNDEM_ID” isimli bir index atıyoruz.
BaseEntity den gelen “Id” kolonu için mapping yapmadık ve Entity Framework bizim için veritabanında “Id” isimli bir kolon oluşturacaktır. “Fluent Api” aracılığı ile tanımlamadığımız tüm mappingler Entity Framework tarafından otomatik oluşturulacaktır.
Oluşturacağımız veritabanını aşağıdaki kod ile kontrol edeceğiz:
Program.cs sınıfı:
Veritabanını oluştururken dafault connection kullanarak yapacağız. Aşağıdaki “DbContext” ten türeyen “GundemContext” sınıfında veritabanı adını verebiliriz ve birçok ayarlamayı da bu sınıf aracılığı ile yapabiliriz. “GUNDEM_DERGISI_DB” isimli bir veritabanı oluşmasını istiyoruz.
Aşağıdaki overwrite ettiğimiz metodu altındaki kodlar aracılığı ile tüm mapping sınıflarını gezerek veritabanı oluşurken Entity Framework’ün dikkate almasını sağlıyoruz.
Artık modelimizden veritabanımızı oluşturabiliriz. “Package Manager Console” u açarak aşağıdaki komutu yazıyoruz:
PM> Enable-Migrations
“Code First” migration etkinleştirildi mesajı aldıktan sonra aşağıdaki komutu çalıştırarak ilk migration sınıfımızı oluşturuyoruz.
PM> Add-Migration Init
Migration sınıfı aşağıdaki şekilde oluşacaktır:
Veritabanımızın oluşmasına tek bir komut kaldı. Aşağıdaki komut aracılığı ile veritabanımızı oluşturuyoruz:
PM> Update-Database
Specify the ‘-Verbose’ flag to view the SQL statements being applied to the target database.
Applying explicit migrations: [201712022032363_Init].
Applying explicit migration: 201712022032363_Init.
Running Seed method.
Ve sonunda veritabanımızı “Code First” yöntemi ile başarılı şekilde oluşturabildik!!!
Peki Code First Yaklaşımı hangi durumlarda kullanmalıyız?
- Veri tabanı bilgisine ihtiyaç olmadan proje geliştirilmek istendiğinde kullanılabilir.
- Veritabanı tasarımında hoşlanmayan yazılımcılar tarafından kullanılabilir.
- İş kurallarının ve işleyişi veritabanında olmasını istenmediği durumlarda. Veritabanı sadece bir saklayıcıdır.
- Model sınıfları iş mantığı içerdiğinde ise kullanılabilir.
- Model sınıflarının standart yapıları yoksa kullanılabilir.
- Veritabanı kısa ömürlü ise kullanılabilir.
- Veritabanı sık değişiyorsa kullanılabilir.
- Ölçeklenebilir uygulamalarda kullanılabilir.
Avantajlar
- Database First ile yapılan herşey yapılabilinir ve kullanımı basittir.
- Yönetmeniz gereken ve sürekli büyüyen bir edmx modeliniz yoktur.
- Migration dosyaları sayesinde veritabanının versiyonları kolaylıkla saklanabilir.
Yapılan tüm değişiklikler framework tarafından saklanmakta ve istenilen versiyona veritanı yapısı da uyumlu şekilde dönülebilmektedir. - Küçük model değişiklikleri herhangibir veri kaybına neden olmaz.
- Daha fazla özelleştirme seçeneğiniz ve kod üzerinde tam denetime sahipsiniz.
- Veritabanında manuel değişiklikler büyük olasılıkla kaybolacaktır çünkü kodunuz veritabanını tanımlıyor.
- Varlıklarınızı istediğiniz gibi çok kolay şekilde, özgürce tasarlayabilirsiniz.
- Modellemede hata oluştuğu durumda Framework bunu size hemen bildirecektir.
Dezavantajlar
- Görsel bir arayüz olmadığı için veritabanını koddan yönetmek sizi zorlayabilir.
- Veritabanını oluşturabilmek için C# bilmeniz gereklidir.
DB First
Db First yönteminde, eski veritabanımızdan sihirbaz kullanarak reverse-engineering yöntemiyle modelimizi EDMX dosyası olarak oluşturuyoruz. Pek çoğumuzu kariyerimiz boyunca Db First ile projeler geliştirmiş ve EDMX dosyalarını kullanmışızdır. Bu nedenle çok fazla ayrıntıya girmeden kısaca değinmek istiyorum.
“Entity Data Model” Shirbazı aracılığı ile kullanacağımız veritabanını seçiyoruz ardından modelde olmasını istediğimiz tabloları, viewleri, store prosedürleri ve fonksiyonları seçerek tamamla butonuna basıyoruz ve modelimiz oluşuyor. Geliştirme aşamasında veritabanı değiştikçe modelimizi güncelleyebiliriz. Bu aşamadan sonra geliştiriciler Entity Framework’ den yararlanabileceklerdir.
Peki DB First Yaklaşımı hangi durumlarda kullanmalıyız?
- Az değişen şemalarla uzun ömürlü veritabanlarında kullanılabilir.
- Modelinizi bir diyagramda görmek ve buradan güncellemek istiyorsanız kullanılabilir.
- Modelinizi çakışmayan diyagramlara bölmek isterseniz kullanılabilir.
- DBA’lar tarafından tasarlanmış bağımsız geliştirilen bir veritabanınız var ise kullanılabilir.
Avantajlar
- Mevcut bir veritabanını kullanabilir ve tablolarınızı ve ilişkilendirmelerinizi orada oluşturabilirsiniz.
- Veritabanı perspektifinden çalışacağınızdan değişikliklerde veri kaybını önlemek kolaydır.
- Store prosedürler ve kullanıcının yarattığı veritabanı fonksiyonlarıyla daha iyi adapte olur.
Dezavantajlar
- İlişkileri, anahtarları, kısıtlamalar vb. veritabanından oluşturma daha zor olabilir.
- Veritabanı değişikliklerini senkronize etmek kolay değil. Yerel makinenizde veritabanınızı değiştirdiğinizi ve o zaman değişikliklerinizi uzak bir veritabanıyla senkronize etmek (commit/rollback) için harici araçlara ihtiyacınız olacaktır. Bu büyük dezavantaj olabilir.
- SVN veya GIT gibi kod sürüm kontrol araçlarını kullanırken, .edmx dosyalarını birleştirmek bazen acı verebilir.
- Üretilen modellerde, hesaplanmış/hesaplanan salt okunur alanlar gibi işlevsellik eklemeniz gerektiğinde, model sınıfını genişleterek güncellemeniz gerekir.
- Veritabanı deployment.
- Entity Framework gelecek versiyonlarda EDMX tabanlı modeli desteklemeyecek gibi görünüyor.
Sonuç
Projenizi yukarıda bahsettiğimiz birçok parametrenin ışığında değerlendirerek, “Code First” veya “DB First” yaklaşımı ile geliştirme yapabiliriz. Fakat güncel teknoloji nedir ve gelecekte yazılımcılar hangi yaklaşımı kullanacaklar sorusunun cevabı kesinlikle “Code First” yaklaşımıdır.
Daha önce çalıştığım bir projede “Code First” yaklaşımı kullanmış bir geliştirici olarak son derece keyif aldığımı söyleyebilirim. Herşeyin geliştiricinin kontrolünde olması ve herşeyin kod üzerinden yapılabildiğini görmek benim için müthiş bir deneyim oldu. Yukarda bahsettiğim birçok avantajı bizzat kendim yaşayarak deneyimledim.
Tabiki koşullar “Code First” yaklaşımını uygulamaya uygun değilse, eski bir veritabanınız var ise, bu durumda “DB First” yaklaşımı ile projenizi geliştirmeniz uygun olacaktır. Yine de yenilik için can atan bir ekip her koşulda “Code First” yaklaşımı ile yeniliklere ve geleceğe yelken açabilir. “Code First” geliştirme yapmak sizin için son derece güzel bir deneyim olacaktır.
Word Doküman :