ADO.NET Ortamında Entity Framework İle Uygulama Geliştirme
Uygulama geliştiriken objeleri kullanmak bilinen bir yöntem. Bu yöntem objeler arasında ilişkiler oluşturmak için referanslar vermeyide içeriyor. Fakat, bu objeleri ve içerdikileri bilgileri bir veri tabanda saklamak istediğimizde ne yapmalıyız? Öncelikle objelerin niteliklerini veri tabanı veri türlerine (sayi, string, tarih vs.) dönüştirmeliyiz. Dahada zorlayıcı olanı diğer iş ise eğer obje bir diğer objeyi yada listesini içeriyorsa bunu veri tabanında primary key ve foreign key kullanarak modellemeliyiz. Ayrıca veri tabanındaki tabloları objelere çevirmek için tersi yönde bir iş daha yapmalıyız. Birçok kod satırı ve zaman gerektiren bir eylem. İşte bu yüzden zaman ve işten tasaruf için nesne ilişkisel eşleme (object-relational mapping) yazılım geliştirme yöntemi kullanılır. Bu yöntem ile objeye dayalı programlama veri türlerine uyumlu olmayan verileri uyumlu hale çevirme bizim için kendiliğinden gerçekleşir. Bu gerçeleştirimi yapan araçlardan biri ise Entitiy Framework (EF).
Entitiy Framework Paketi
Bu yazımda Microsoft Visual Studio 2013 kullanacağım. Objeye dayalı programala dili ile bir veri tabanı kullanarak çok sade bir örnek vereğim. EF araçları Visual Studio 2013 içerisinde entegre olarak bilgisayarımıza kuruluyor. Bu konuda bir şey yapmamıza gerek yok. Fakat EF runtime için bir paket bulunuyor. Bu paketi indirip kurmamız gerekli. Bunu yapabilmek içinde bir paket yöneticisine ihtiyacımız var NuGet.
NuGet Paket Yöneticisinin Kurulumu
Paket yöneticisini yüklemek için yapmamız gereken şey Tools
> Extensions and Updates...
yolunu izlemek.
Sağ kısımda Online
kategorisinde arama kutusuna nuget package manager
yazarak arama yapın ilk çıkacak sonuç bizim yükleyeceğimiz paket yöneticisinin kendisi.
Daha sonra Install
butonuna basarak kullanıcı sözleşmesini kabul edip programı kuruyoruz.
Yapılan değişiklerin etki etki etmesi için Restart Now
butonu ile Visual Studio programını tekrar başlatıyoruz.
Artık Tools
menüsü altında NaGet Package Manager
alt menüsünü görebiliriz.
Entity Framework Paketini Yüklemek
Paketi iki şekilde yükleyebilirsiniz, bir kere yükledinizmi diğer projelirinizde kullanamak için tekrar yüklemenize gerekte kalmaz. Bu yöntemler şunlardır:
1. Paket Yöneticisi Konsolu
Tools
menüsündeki NaGet Package Manager
menüsü altında Package Manager Console
ile konsol ekranına erişebiliriz.
Bu konsol ekranında EF paketini yükelemek için şu komutu yazıp çalıştırın (Not: PM>
yazılmayacak):
PM> Install-Package EntityFramework
Komutun muhtemel çıktısı:
Installing 'EntityFramework 6.1.0'.
You are downloading EntityFramework from Microsoft, the license agreement to which is available at http://go.microsoft.com/fwlink/?LinkID=320539. Check the package for additional dependencies, which may come with their own license agreement(s). Your use of the package and dependencies constitutes your acceptance of their license agreements. If you do not accept the license agreement(s), then delete the relevant components from your device.
Successfully installed 'EntityFramework 6.1.0'.
Adding 'EntityFramework 6.1.0' to WpfApplication2.
Successfully added 'EntityFramework 6.1.0' to WpfApplication2.
Type 'get-help EntityFramework' to see all available Entity Framework commands.
Ayrıca şu komutla Solution içerisindeki varsayılan projede kullanılan NuGet paketlerini listeyebilirsiniz:
PM> Get-Package
Bu komutla aynı yerdeki güncellemesi mevcut olan paketleri listeleyebilirsiniz:
PM> Get-Package -Updates
2. NuGet Paket Yönetme Arayüzü
Solution Explorer
panelinde projenizin References
kısımını sağ tıklayıp Manage NuGet Packages...
menü seçeneği ile bu arayüze erişebilirsiniz.
Arayüz karşınıza çıktığı zaman arama kutusuna Entitiy Framework
yazıp aramdaki ilk sonucu yüklemeniz paketi yüklemek için yeterli olacaktır.
Uygulama Geliştirme
Gerekli paketi yüklediğimize göre .NET ortamında uygulama geliştirirken nasıl kullanılacağına değinebiliriz artık. Şimdi çok basit bir örnek ile başlayalım. Bir C# ile WPF projesi yapacağımızı var sayalım. Projemizin adını üzerine sağ tıklayıp Add
> New Item...
alt menüsüne tıklayalım.
Daha sonra Visual C#
> Data
kategorisinde ADO.NET Entity Data Model
nesnesini seçelim.
Karşımıza Entity Data Model Wizard
arayüzü çıkacak. İşte bu kısımda bize iki seçenek sunulmakta. Var olan bir veri tabanı kullanmak (Generate from database
) yada boş bir modeli kendimiz doldurmak (Empty model
). Eğer elimizde hali hazırda bir veri tabanı bulunuyorsa ve onu kullanmayı düşüyorsak ilk seçeneği, elimizde bir veri tabanı bulunmuyorsa ikinci seçeneği seçmeliyiz.
Bizim elimizde bir veri tabanı olduğunu varsayalım. Next
butonu ile ilerlediğimizde bir veri tabanına bağlanmamızı isteyen arayüz bizi karşılayacaktır. Benim öreğimde bilgisayarımda yerelde bulunan AdventureWorks2012 veri tabanına bağlanıyorum. Veri kaynağını belirten bağlantı karakter dizisini (connection string) daha sonra değiştirmek istiyorsak projemizdeki App.Config
dosyasında Save entity connection settings in App.Config as:
kutusundaki isimli değeri değiştirimemiz yeterlidir.
Bize hangi EF sürümünü kullacağımız soran bir arayüz karşılayacak. Yeni sürümlerin getirdiği özellikler ve değişiklere şu adresten ulaşabilirsiniz.
Ve en sonunda bizi veri tababının hangi tablolarını vs. kullanıp modeli oluşturacağımızı soran bir arayüz ile karşılaşacağız. Ben tüm veri tabanı yerine örnek vermek amacıyla sadece bir kısımını kullanıyorum. Buradaki Pluralize or singularize genereted object names
seçeneğinin anlamı bir nesnenin koleksiyonunun isimi o nesnenin çoğul isimi olarak kullanmaktır. Örneğin EmailAddress
nesnesinin birden fazla elmanlı koleksiyonu EmailAddresses
olarak isimlendirilecektir.
Entity Data Model
EF varlıklar ve aralarındaki ilişkileri belirtmek için Entity Data Model (EDM) tekniğini kullanır. Bu modeli düzenlemize yarayan EF Designer varsayılan olarak Visual Studio 2013 içerisindedir. Örneğin aşağıdaki veri tabanının varlık-bağıntı modeline (entity-relationship model (ER)) bir göz atalım.
EF bu ER modelini otomatik olarak EDMe dönüştürür ve kullanımıza sunar. Aşağıda bu iki tablonun C# sınıflara dönüştürülerek nasıl modellendiğini görebilirsiniz.
Böylece Person
sınıfının EmailAdresses
adında EmailAdress
sınıfı nesnelerinden oluşan bir kolaksiyona sahip olduğunu görürüz. Aynı şekilde EmailAdress
sınıfının bir Person
alanı bulunmakta. Böylece bir kişinin sahip olduğu mail adreslerine o kişinin nesnesi üzerinden erişebilir aynı şekilde bir mail adresinin sahibine o nesne üzerinden erişebiliriz.
Farklı bir seçenek olarak EDM kullanmak için elinizde bir veri tabanı bulunmasına gerek yoktur. Yukarıda belirttiğim iki seçenekten biri Empty model
ile boş bir EDM kullanarak EF Designer ile veri modelimizi oluşturabiliriz. Böylece veri tabanı veri türleri ile C# veri türleri arasındaki uyumsuzluğu düşünmemize gerek kalmaz. Bu dönüşümü EF bizim için gerçekleştirir.
Kodlama
Artık veri modelimiz projemize eklendiğine göre bu yeni sınıfları kullanmaya başlayabiliriz. Benim örneğimde DemoEntities
olarak adlandırdığım sınıf veri tabanı bağlantısını ve varlık nesnelerini tutan bir sınıftır. Bu sınıf değişiklik takibi, ayrıt edici özellik takibi vs. işleri gereçekleştirir ve LINQ-tabanlı veri erşimi sağlar. Bu sınıfın myE adında bir nesnesini oluşturalım.
DemoEntities myE = new DemoEntities();
Artık elimizde kayıtlı olan verilere sınıflar araclığı ile erişebiliriz. Mesela Person
tablosunda kayıtlı olan ve id numarası 1 olan (tablodaki id kolonunun isimini yazmayada gerek yok) nesneyi elde etmek için:
Person p = myE.People.Find(1);
Daha sonra bu elde ettiğimiz nesnenin özelliklerini değiştirebiliriz:
Person p = myE.People.Find(1);
p.name = "XXXXX";
p.lastname = "YYYYY";
Elimizde kaydı olan bir veriyi değiştirmek yanında yeni bir veri kaydı oluşturabilir yada bir veri kaydını bir daha kullanmamak adına silebiliriz. Yeni bir Person
nesnesi oluşturduğumuzu varsayalım:
Person p_new = new Person();
p_new.personId = 4;
p_new.name = "XXXXX";
p_new.lastname = "YYYYY";
Bununla arkaplanda bu nesnenin var olduğu tablodaki satır hücrelerini doldurmuş oluyoruz. Fakat Person
tablosu ile EmailAdress
tablosu arasındaki foreign key ilişkisini nasıl tanımlayacağız? Bunu bir tablo hücresi doldurmak yerine o nesnenin ilgili alanındaki karşılığını yazarak yapabiliriz:
EmailAdress email = new EmailAdress();
email.email_id = 5;
email.email = "a@b.com";
p_new.EmailAdresses.Add(email);
Artık yeni oluşturduğumuz p_new nesnesi ile temsil ettiğimiz kişinin mail adresi email isimli nesne olacaktır.
Var olan veri sisteminde kayıtlara id ile erişmek yerine myE
nesneside yer alan nesne koleksiyonlarında where
fonksiyonu ile LINQ kullanarak sorgular yapabiliriz. Mesela isimi Henry olan tüm kişileri elde etmek için:
var p_where = myE.People.Where(prs => prs.name == "Henry");
Değişiklikleri Kaydetme
Eğer yeni bir kayıt için nesne oluşturduysak bunu var olan nesne koleksiyonuna eklememiz gerekli. Yoksa bu yeni kayıt arkaplanda veri tabanında muhafaza edilmez.
myE.People.Add(p_new);
Var olan kayıtları temsil eden nesnelerdeki yaptığımız değişikler (isimini değiştirmek gibi) ve eklediğimiz yeni nesneleri veri tabanına kaydetmek için şu fonksiyonu myE
nesnesi üzerinden çağırmalıyız:
myE.SaveChanges();
Sonunda EF ile oluşturulan nesneleri kullanarak arkaplandaki veri tabanını düşünmeden yazdığımız kod ile verilerimiz kayıt altında olacak. Bunun sayesinde veri tabanı ile kod arasındaki ilişkiyi sağlamak için harcayacağımız efor minimuma ulaşmış oldu.
Bence güzel bir yöntem.
EF ADO.NET .NET Framework Database Visiual Studio