Entity Framework İle Code First Yaklaşımı

Merhaba,

Linq To SQL gibi Entity Framework mimariside biz yazılımcılara oldukça hız kazandırmakta ve veritabanı işlemlerinde atılan bir çağın basamaklarını teşkil etmektedir. Haliyle biz yazılımcılar ister istemez bu mimarilere yönelmekte ve meraklarımızın yanında çalışmalarımızı da bu mimarilerle sürdükmekteyiz. Tabi günümüzde bir yapı yahut mimariye yönelirken kendimize uygun prensip ve yaklaşım seçmemiz yaşayacağımız karışıklığı ortadan kaldıracaktır. Burada demek istediğim o ki, günümüzde her mekanizmasının birden fazla yaklaşımı ve prensibi mevcut olduğundan, öğrenme sürecinde kaçınılmaz olarak kaynakların farklılıkları kafanızı karıştıracaktır. İşte bunun sebebi, her kaynağın farklı bir yaklaşımı merkez edinmesindendir.

Entity Framework mimarisinde temelde üç adet yaklaşım mevcuttur.

  • Code First
  • Database First
  • Model First

Bu yazımızda Code First yaklaşımı üzerine duracağız. Zamanla diğer yaklaşımlar üzerinde de istişaremizi ederiz diye umuyorum.

Code First Nedir?

Veritabanı ile Programlama dili arasında bağ kuran bir tekniktir. Projenizde veritabanı işlemlerinizi mümkün mertebe Visual Studio tarafında kod yazarak gerçekleştirmenizi sağlayan bir yaklaşımdır. Bu yaklaşım sayesinde veritabanı arayüzü ile yazılımcı arasında ilişki minimize edilmektedir.

Code First yapısında programlama dilindeki “class” yapıları veritabanındaki “tablo” yapılarına, “property” yapıları ise veritabanındaki “kolon” yapılarına denk gelmektedir.

Ayrıca Attribute’lar sayesinde veritabanı yapılarına Validationlar uygulanabilmekte ve kolonlara belirli şartlar veyahut kısıtlamalar koyulabilmektedir.

En önemlisi ise projenizdeki modelin oto kontrolünü elinizde hissetmenize ve tam hakimiyetle istediğiniz gibi kullanmanıza olanak tanıyor. Database First yaklaşımı Linq To SQL yapısındaki gibi sürükle bırak mantığıyla çalışmakta ve herşeyi otomatik halletmektedir. Eee bir yazılımcının en büyük arzusu; tez işte tam hakimiyet… İşte Code First böyle bir çizgiye sahiptir.

Projeye Entegrasyonu ve Code First Yapısının İnşası

Öncelikle yapmamız gereken, üzerinde çalıştığımız projeye Entity Framework Nuget paketini eklemektir.

“Tools” -> “Nuget Package Manager” -> “Manage Nuget Packages for Solution…” kombinasyonunu takip edin.

Entity Framework İle Code First Yaklaşımı

Entity Framework İle Code First Yaklaşımı

Açılan pencerede aşağıdaki gibi “entity” anahtar kelimesini aratın. Listede karşınıza çıkan “EntityFramework” paketini Install ediniz.

Entity Framework İle Code First Yaklaşımı

Entity Framework İle Code First Yaklaşımı

Yüklemeyi gerçekleştirdikten sonra gerekli Entity Framework referansları projeye entegre edilmiş bulunmaktadır.

Şimdi sıra geldi Code First yapısıyla bir model oluşturmaya. Haliyle oluşturma aşamasında inşa sürecinide görmüş olacağız.

Hatırlarsanız eğer Code First yapısı veritabanı işlemlerini programatik olarak gerçekleştirmemize yarayan bir yaklaşım sergilemekteydi. O halde örnek olarak çalışacağımız projede hem veritabanı oluşturacağız, hem de Code First yapısının diğer nimetlerinden faydalanacağız.

Gelin tüm teferruatınca şu konuyu ele alalım…

Entity Framework İle Code First Yaklaşımı

Entity Framework İle Code First Yaklaşımı

Code First ile tüm modele hakimiyet sağlamanın ekstra getirisi kodlara disiplinli bir hiyerarşik düzen sağlamanın sorumluluğu getirmesidir. Haliyle modele tam hakimeyet demek, a’dan z’ye biz kodlayacağız demek. O yüzden entitylerimi(yani tabloları) “Entity” klasörüne, yazılım ile server arasında iletişimi sağlayacak olan Context sınıfını da “Context” klasörüne oluşturacağım.

Şimdi Code First ile bir veritabanı oluşturmayı ve bu veritabanı içerisine bir tablo eklemeyi görelim.

    class OrnekTablo
    {
        public int ID { get; set; }
        public string Kolon1 { get; set; }
        public string Kolon2 { get; set; }
    }

Öncelikle tablomuzu temsil eden sınıfımı oluşturdum. Şimdi veritabanı ile bağlantı kuracağımız Context sınıfını oluşturuyorum.

    class OrnekVeriDbContext : DbContext
    {
        public DbSet<OrnekTablo> OrnekTablos { get; set; }
    }

Context sınıfımızı incelerseniz eğer DbContext sınıfından türemektedir. Bunun sebebi, Entity Framework mimarisinin nimetlerine bu sınıfın mirasından erişebilecek, ayriyetten ilgili sınıfımızın bir Context sınıfı olmasını sağlayacaktır. “OrnekVeriDbContext” sınıfına verdiğimiz isim bizim için oldukça önemlidir.

Code First yapısında en temel nokta, veritabanındaki tablolaları temsil edecek Generic yapıdaki DbSet tipinden propertyler olarak tutmasıdır. Yukarıda gördüğünüz “OrnekTablos” isimli property, bizim “OrnekTablo” isimli tablomuzun, veritabanındaki fiziksel yansımasını oluşturacaktır.

İşte en temelde de olsa Code First yapısında bir veritabanı dizayn ettik ve sıra bu veritabanını oluşturmaya geldi. Peki… Oluşturduğumuz bu yapı, hangi Server’da hangi isimde veritabanı oluşturacağını biliyor mu? hayır…
İşte bu bildiriyi de eğer web kısmında çalışıyorsanız “web.config” dosyasında, yok eğer masaüstünde takılıyorsanız “app.config” dosyasında belirtebilirsiniz.

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <configSections>
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
  <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 --></configSections>
  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
  </startup>
  <entityFramework>
    <defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
      <parameters>
        <parameter value="mssqllocaldb" />
      </parameters>
    </defaultConnectionFactory>
    <providers>
      <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
    </providers>
  </entityFramework>
  <connectionStrings>
    <add name="OrnekVeriDbContext" connectionString="Server=.;Database=OrnekVeritabani;Trusted_Connection=true;" providerName="System.Data.SqlClient"/>
  </connectionStrings>
</configuration>

Yukarıdaki app.config dosyasına “connectionStrings” node’ı eklenerek gerekli ayarlama yapılmıştır. Tabi, sizlerin net görebilmesi benimde net izah edebilmem için ilgili parçayı aşağı almamız uygun olacaktır.

.
.
.
  <connectionStrings>
    <add name="OrnekVeriDbContext" connectionString="Server=.;Database=OrnekVeritabani;Trusted_Connection=true;" providerName="System.Data.SqlClient"/>
  </connectionStrings>
.
.
.

Gördüğünüz gibi bir connectionStrings node’ı açıyor ve içerisine ekleme yapıyoruz. “name” özelliğine Context sınıfımızla birebir aynı ismi veriyoruz. Bunda zorunlu değiliz lakin başka Context’lere nazaran karışıklığı önlediği için tavsiye ediyorum. “connectionString” Attribute’una bildiğiniz Provider’ımızı yazıyoruz. Ama burada dikkat!!! Yazdığınız bu Provider’da ki veritabanı olmayan bir veritabanı olması gerekiyor. Olması gerekiyor ki, Code First yapısı kendisi oluşturabilsin. Bunların yanında “providerName” Attribute’u sayesinde ilgili bağlantının System.Data.SqlClient kütüphanesinde çalışacağını, yani SQL Server olduğunu belirtmiş oluyoruz.

Bu işlemlerden sonra Program.cs sınıfında “OrnekVeriDbContext” sınıfından bir nesne üretip ilk oluşumu seyredebiliriz.

    class Program
    {
        static void Main(string[] args)
        {
            OrnekVeriDbContext Veri = new OrnekVeriDbContext();
            Veri.Database.Create();
        }
    }

Yukarıdaki kod bloğunu çalıştırdığımız zaman neler olmuş bakalım…

Entity Framework İle Code First Yaklaşımı

Entity Framework İle Code First Yaklaşımı

Anahh 🙂 Gördünüz mü, app.config dosyasında belirttiğim isimde bir veritabanı oluşturulmuş ve “OrnekTablo” isminde bir tablo eklenmiştir. Tabi oluşturma aşamasında Entity Framework mantığı işte “OrnekTablo” değil “OrnekTabloes” olarak çoğul maksatlı bir isimde eklenmiştir. Eee bunun niyeti, Linq To Sql’de olduğu gibi çoğul olanları belirleyebilmektir. Velhasıl sonraki yazılarımızda bu tarz tablo isimleri vs. gibi değerlere, tablo oluşum sürecinde müdahale edecek ve istediğimiz değişikliği uygulayabileceğiz.

Şimdi dikkatlerinizi oluşturulan tablonun kolonlarına çekmek istiyorum. Biz hiç bir işlem yapmadığımız halde nasıl oluyorda ID kolonu primary key olmuş oluyor? ve hatta identity özelliğine bakarsanız eğer birer birer arttığını bile görebilirsiniz.

Bunun sebebi; Code First yapısında, tablo olarak dizayn edilen sınıfta tanımlanmış ilk property otomatik olarak primary key görülüyor ve identity özelliği bire birden default atanıyor. O yüzden ilk propertynin ID olduğunu belirtecek bir isim vermeye dikkat etmenizi öneriyorum.

Şimdi bu bilgiyi unuttuk, ya da farklı bir isimde primary key kolon tanımlamak istiyorum diyorsanız aşağıdaki kod bloğunu inceleyiniz.

    class OrnekTablo
    {
        public int hilmi { get; set; }
        public string Kolon1 { get; set; }
        public string Kolon2 { get; set; }
    }

Varsayalım, ilk propertymizin ismi “hilmi” olsaydı ne gibi bir durumla karşılaşırdık.

An unhandled exception of type ‘System.Data.Entity.ModelConfiguration.ModelValidationException’ occurred in EntityFramework.dll

Additional information: One or more validation errors were detected during model generation:

EFCodeFirst.Model.Context.OrnekTablo: : EntityType ‘OrnekTablo’ has no key defined. Define the key for this EntityType.

OrnekTablos: EntityType: EntitySet ‘OrnekTablos’ is based on type ‘OrnekTablo’ that has no keys defined.

Evet yukarıdaki gibi ilk propertymiz “hilmi” olsaydı bu hata mesajıyla karşılaşırdık. Hatta hata mesajının görselinide paylaşmak gerekirse buyurun.

Entity Framework İle Code First Yaklaşımı

Entity Framework İle Code First Yaklaşımı


Bu hatanın yegane sebebi, “hilmi” isminde bir kolonun primary olma ihtimalinin sıfır olmasıdır. Yani derleme aşamasında mimari bizden tablo ismiyle benzer ya da sadece id kolonu olduğunu belirten bir property istediğini belirtiyor.

Haliyle bizler tutturup illa ki “hilmi” kolonunun primary key olmasını istiyorsak eğer “Key” Attribute’unu ilgili propertye uygulamalıyız.

    class OrnekTablo
    {
        [Key]
        public int hilmi { get; set; }
        public string Kolon1 { get; set; }
        public string Kolon2 { get; set; }
    }

Entity Framework İle Code First Yaklaşımı

Entity Framework İle Code First Yaklaşımı


Ekran görüntüsünde de gördüğünüz gibi “hilmi” isminde bir primary key kolon oluşturmuş olduk. Biliyorum çok gülünç 😀 😀
Uzun lafın kısası burada anlatmak istediğim, tablonuzun ismi “A” ise ilk propertyi “AId”, “AID” veyahut “ID” gibi isimler vermeniz Entity Framework Code First açısından kabul edilebilir bir durum olacaktır.

Code First İle Veri Ekleme / Silme / Güncelleme

Aslında Code First’e özel bir ekleme/silme veyahut güncelleme işlemi gerçekleştirmeyeceğiz. Şuana kadar yaptığımız işlemler neticesinde bir Entity Framework mimarisinde kullandığımız normal veri modifikasyonu metod ve yöntemlerini ele alacağız.

Entity Framework İle Code First Yaklaşımı

Entity Framework İle Code First Yaklaşımı

Yukarıdaki ekran görüntüsünde de gördüğünüz gibi “OrnekVeriDbContext” Context sınıfımız içerisinde DbSet tipinde tuttuğum “OrnekTablos” isimli property’imi görüyorsunuz. İşte Code First yaklaşımında Context sınıfı bu propertye, veritabanındaki tabloyu fiziksel getirmekte ve içindeki her bir veriyi bize “OrnekTablo” tipinden vermektedir.

    class Program
    {
        static void Main(string[] args)
        {
            OrnekVeriDbContext Veri = new OrnekVeriDbContext();
            Veri.OrnekTablos.Add(new OrnekTablo
            {
                Kolon1 = "Örnek veri kolon1 1",
                Kolon2 = "Örnek veri kolon2 1"
            });
            Veri.SaveChanges();
        }
    }

Bu şekilde veri eklenebilmekte,

    class Program
    {
        static void Main(string[] args)
        {
            OrnekVeriDbContext Veri = new OrnekVeriDbContext();
            OrnekTablo ornek = Veri.OrnekTablos.FirstOrDefault(o => o.ID == 1);
            ornek.Kolon1 = "Örnek veri kolon1 güncel";
            ornek.Kolon2 = "Örnek veri kolon2 güncel";
            Veri.SaveChanges();
        }
    }

bu şekilde veri güncellenebilmekte,

    class Program
    {
        static void Main(string[] args)
        {
            OrnekVeriDbContext Veri = new OrnekVeriDbContext();
            OrnekTablo ornek = Veri.OrnekTablos.FirstOrDefault(o => o.ID == 1);
            Veri.OrnekTablos.Remove(ornek);
            Veri.SaveChanges();
        }
    }

bu şekilde veri silinebilmekte
ve

    class Program
    {
        static void Main(string[] args)
        {
            OrnekVeriDbContext Veri = new OrnekVeriDbContext();
            foreach (var item in Veri.OrnekTablos)
            {
                Console.WriteLine($"{item.Kolon1} {item.Kolon2}");
            }
            Console.Read();
        }
    }

bu şekilde verileri çekebiliyoruz.

Bu yazımızda Entity Framework Code First yapısına giriş yaparak, bir projeye entegrasyonun nasıl sağlanacağını, yapısal olarak nasıl bir çalışma sergilenmesi gerektiğini ve temel veritabanı işlemlerini incelemiş olduk.

Hemen bir sonraki yazıda Code First yöntemiyle tablolar arasında ilişkinin nasıl kurulacağını inceleyeceğiz.

Eee o halde sonraki yazımda görüşmek üzere…

İyi çalışmalar…

Bunlar da hoşunuza gidebilir...

17 Cevaplar

  1. Doğancan Kasap dedi ki:

    Gençay bey connectionstringde initial catalog kısmı sanırım unutulmuş. Ben de fark etmeden çalıştırdığımda 403 hatası aldım. Bilginize.

    Güzel makalelerle bilgi veriyorsunuz. Sitenizi takip ediyorum, verdiğiniz değerli bilgiler için teşekkür ederim.

  2. Ramazan dedi ki:

    Merhabalar

    Benim söyle bir sıkıntım var.Bir tablonun key kısmını değiştirdiğimde aşağıdaki gibi hata veriyor.
    Sizin yapmış oldugunuz örnegin aynısını yaptım. Fakat yine sonuc aynı. Siz örnekte dbyi silip tekrardanmı oluşturdunuz? Eğer silip tekradan oluşturduysanız sorumu su sekilde değiştirmem gerekiyor. Canlı sistemde buşekilde bir güncellemeye ihtiyacım olursa nasıl yapacagım?

    One or more validation errors were detected during model generation:

    Teşekkürler

  3. Berkay dedi ki:

    Gerçekten süper bi site açıklamalarınız anlaşılır ve adım adım

  4. test30 dedi ki:

    Merhaba bununla Asp.net Core ile örnek bir makaleniz olacak mı ?

  5. dilek dedi ki:

    merhabalar 1 haftadır uğraşıyorum yetiştirmem gereken bir projem var ancak enable-migrations işleminde takılıyorum No context type was found in the assembly hatası alıyorum -verbose yaparak da denedim ancak sorunu çözemiyorum bir öneriniz var mıdır ? umarım vardır delirmek üzereyim zira

  6. Sezer Ali dedi ki:

    Ilk defa bır blog sitesine yorum yazıyorum. Tebrikler güzel yazı olmuş.. Yeni başlayanlara göz korkutmadan anlatmaya çalışmışsınız. Tek sıkıntım türkçe karaktere uygun yazı tipi seçmeniz olabilir.
    Kolay gelsin…

    • Gençay dedi ki:

      🙂 Türkçe karakter konusunda çok şikayet alldığımı bilmenizi isterim. Ama üşengeçliğin kabuğunu kıramıyorum 🙂
      Güzel yorumun için teşekkürler.
      İyi çalışmalar.

  7. Ercan dedi ki:

    Merhaba proje çalıştığında, mssql veri değiştirdiğimde projeyi kapatıp açmadan değişiklik görünmüyor. ne yapabilirim.

  1. 22 Mart 2016

    […] önceki Entity Framework İle Code First Yaklaşımı başlıklı yazımda Entity Framework – Code First yaklaşımına giriş yaparak nasıl […]

  2. 26 Mart 2016

    […] yaptığımızı varsayıyorum. Eğer bu işlemler hakkında bir fikriniz yoksa öncelikle Entity Framework İle Code First Yaklaşımı başlıklı makalemi […]

  3. 02 Nisan 2016

    […] bilginiz yok veyahut tekrardan hatırlamak istiyorsanız öncelikle makalemizi temellendireceğimiz Entity Framework İle Code First Yaklaşımı ve Entity Framework – Code First Migrations İşlemleri başlıklı yazılar başta olmak üzere […]

Bir cevap yazın

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