You are on page 1of 16

1

ADO.NET Entity





Abdullah URAKAN
Web Developer










apoStyLEE.com
twitter.com/apoStyLEE
2

indekiler
ADO.NET ENTTY NEDR ? ................................................................................................................................. 3
NEDEN ENTTY ? ...................................................................................................................................................... 3
MODEL YAKLAIMLARI ..................................................................................................................................... 3
BAST BR MODEL ............................................................................................................................................. 4
DBCONTEXT ........................................................................................................................................................... 4
EKLE, LSTELE, DZENLE VE SL (CRUD) ............................................................................................................. 5
DORULAMA (VALDATON) ............................................................................................................................ 7
LKLER (RELATONSHP) ................................................................................................................................ 8
1 DEN OA (1 TO N) LK ....................................................................................................................................... 8
OKTAN OA (N TO N) LK .................................................................................................................................. 11
COMPLEXTYPE ................................................................................................................................................ 12
ADO.NET FLUENT AP ..................................................................................................................................... 14
PULARI ........................................................................................................................................................ 15
WHERE ................................................................................................................................................................ 15
SELECT ............................................................................................................................................................... 15
ORDERBY ............................................................................................................................................................. 15
TOP, MAX, MN .................................................................................................................................................... 15
SQLQUERY, EXECUTESQLCOMMAND ......................................................................................................................... 16
SON SZ ......................................................................................................................................................... 16

3

Ado.Net Entity Nedir ?
Ado.Net Entity, Microsoft un Orm
1
aracdr. Bu aralar, veritaban ilemlerini nesneler zerinden
yapmamza olanak salayan yaplardr. Veritabannda bulunan her tabloya karlk gelen bir nesne
bulunmaktadr. Veritabanna ekleme, silme, listeleme vb.. iler bu nesneler kullanlarak, gvenli ve
hzl bir ekilde yaplr. Orm aralarnn dier bir zelliide veritaban bamlln ortadan
kaldrmasdr. Projenizi mssql veritaban kullarak gelitirip sonrasnda mysql e evirebilirsiniz. Buna
imkan veren ise; projenizde sql kodu kullanmadan her eyi nesneler zerinden gerekletirmenizdir.
Neden Entity ?
.Net projelerimizde farkl orm aralar kullanmamzda mmkn, rnein nHibernate. Bizim Entity i
sememizdeki en byk etken, Microsoft un rn olmas ve Visual Studio ile birlikte gelen
zelliklerle birlikte ok daha etkin kullanlabiliyor olmas.
Model Yaklamlar
Ado.Net Entity Framework bize modelimizi oluturmamz iin 3 seenek (ekil 1) sunuyor. Bunlar;
1. Database First Var olan bir veritabanndan modelimizi oluturduumuz yaklam.
2. Model First Oluturduumuz data modelden
2
, veritabann oluturduumuz yaklam.
3. Code First Model snflarn elle yazdmz yaklam. Bizim ilgileneceimiz yaklam bu olacak.

ekil 1 (Model Yaklamlar)



1
Orm; Object-relational mapping kelimelerinin ksaltlm halidir. Detayl bilgiye buradan ulaabilirsiniz.
2
Data Model; modeli bir editr tarafndan tasarladmz ve modelimize ait snflar, metotlar ve dier kodlar
otomatik oluturan yaklam oluyor.
4

Basit bir model
Model; veritabannda ki tablomuza karlk gelen bir snftr (class). Modelimiz de ayn zamanda
ilikileride (relationship) tanmlyoruz, bunu ilerleyen sayfalarda greceiz.

public class kullanici
{
public int id { get; set; }
public string adi { get; set; }
public string soyadi { get; set; }
public string eposta { get; set; }
public string sifre { get; set; }
public DateTime kayitZamani { get; set; }
}


kullanici veritabannda ki tablo adn ifade eder.
id, adi, soyadi.. tabloda ki alanlar ifade eder.
o id alan entity framework tarafndan otomatik olarak alglanp, otomatik artan birincil
anahtar (primary key) olarak belirlenir. Bu alan tabloAdiId (kullaniciId) eklinde de
kullanabiliriz. Farkl bir alan birincil anahtar olarak belirlemek istersek, alann bana
[Key] aklamasn (Annotations) eklememiz yeterli olacaktr. Bu olay salayan
Ado.Net Fluent Api adnda ki yap. lerleyen sayfalarda detayl bir ekilde deineceiz.
int, string, datetime.. alanlarn trlerini ifade eder.
DbContext
public class adoNetKitapContext : DbContext
{
public DbSet<kullanici> kullanicis { get; set; }
}

Oluturduumuz modelin anlam kazanmas iin bir balam (context) oluturmamz gerekiyor. Bu
context bizim modelimizi kullanp veritaban ilemlerimizi yapmamza olanak salyor.
adoNetKitapContext hem contextimizin hemde web.config ierisine yazacamz balant
cmlesinin (connection string) ad oluyor.
DbSet<kullanici> kullanacamz model snfmz belirtiyoruz.
kullanicis buda veritaban ilemleri iin kullanacamz methodlar iinde barndran
snfmzn adn ifade ediyor. Ayn zamanda veritaban otomatik
3
oluturulduunda tablo
adnda ifade ediyor.
Veri katmanmz basite bu ekilde oluturuyoruz. imdi basit bir rnekle veritabanna ekleme,
listeleme, gncelleme ve silme (CRUD) ilemlerine bir gz atalm.

3
Orm aralar veritabann modelinizdeki tanmlara gre otomatik olarak olutururlar. Ado.Net Entity projenizi
altrdnzda context iindeki tanmlara gre modelinizi oluturacaktr.
5

Ekle, Listele, Du zenle ve Sil (CRUD)
Yukarda ki modelimizi kullanarak aadaki gibi veritaban ilemlerini yapabiliriz. ncelikle
web.config ierisine veritaban balants iin gerekli olan balant cmlemizi yazyoruz. Ben Sql
Compact 4
4
veritabann kullanyorum.
<add name="adoNetKitapContext" connectionString="Data Source=|DataDirectory|\db.sdf"
providerName="System.Data.SqlServerCe.4.0" />

public void Crud()
{
// context imizi tanmlyoruz.
adoNetKitapContext context = new adoNetKitapContext();

// Kullanc modelimiz
kullanici k = new kullanici();
k.adi = "Ahmet";
k.eposta = "ahmet@ahmet.com";
k.kayitZamani = DateTime.Now;
k.sifre = "123";

// Veritabanna kayt ekleme
context.kullanicis.Add(k);
context.SaveChanges();

// Kaytlar listeleme
var kayitListesi = context.kullanicis.ToList();

// Kayt gncelle
int gKayitId = 1;
var guncellenecekKayit = context.kullanicis.Find(gKayitId);
guncellenecekKayit.adi = "yeni deer";
guncellenecekKayit.soyadi = "yeni deer";
context.SaveChanges();

// Kayt silme
int sKayitId = 1;
var silinecekKayit = context.kullanicis.Find(sKayitId);
context.kullanicis.Remove(silinecekKayit);
context.SaveChanges();
}

Grld zere hibir sql kodu yazmadan veritaban ilemlerini gerekletirdik. imdi arka planda
neler olduuna bir gz atalm. Gzlemleme iini Sql Server Profiler ile yapacam iin ncelikle
web.config de bulunan balant cmlemi Mssql veritaban kullanmak iin deitiriyorum. * Orm
aralarnn bir avantajda veritaban bamszlyd.
<add name=" adoNetKitapContext"
connectionString="Server=localhost;Database=dbName;User ID=sa;Password=pass;"
providerName="System.Data.SqlClient" />


4
Sql Compact 4; ek ykleme yapmadan direk kullanabileceiniz bir veritabandr. 4Gb a kadar verileri
depolayabilir ve cretsiz olduundan datmda dk maliyet salar. Transact-SQL kullanmn destekler. Takm
gnlne http://blogs.msdn.com/b/sqlservercompact/ adresinden ulaabilirsiniz.
6

Crud ilemlerini altrdmzda Sql Server Profiler da gzlenen sql sorgular aadaki gibidir.
Ado.Net Entity nesnelerle gerekletirdiimiz ilemleri bu ekle evirip sql servera iletiyor. lemler
parametre kullanlarak gerekletirildiinden, sql enjeksiyon
5
saldrlarna karda gvenli bir hale
geliyor.


5
Sql enjeksiyon bir saldr eklidir. Buradan http://ferruh.mavituna.com/sql-injection-a-giris-ve-sql-injection-
nedir-oku/ konuyla ilgili detayl bilgiye ulaabilirsiniz.
// Ekleme ilemi
exec sp_executesql N'insert [dbo].[kullanicis]([adi], [soyadi], [eposta], [sifre], [kayitZamani])
values (@0, null, @1, @2, @3)
select [id]
from [dbo].[kullanicis]
where @@ROWCOUNT > 0 and [id] = scope_identity()',N'@0 nvarchar(max) ,@1 nvarchar(max)
,@2 nvarchar(max) ,@3
datetime2(7)',@0=N'Ahmet',@1=N'ahmet@ahmet.com',@2=N'123',@3='2011-07-12
17:16:30.3015048'
go


// Listeleme ilemi
SELECT
[Extent1].[id] AS [id],
[Extent1].[adi] AS [adi],
[Extent1].[soyadi] AS [soyadi],
[Extent1].[eposta] AS [eposta],
[Extent1].[sifre] AS [sifre],
[Extent1].[kayitZamani] AS [kayitZamani]
FROM [dbo].[kullanicis] AS [Extent1]
go


// Gncelleme ilemi
exec sp_executesql N'update [dbo].[kullanicis]
set [adi] = @0, [soyadi] = @1
where ([id] = @2)
',N'@0 nvarchar(max) ,@1 nvarchar(max) ,@2 int',@0=N'yeni deer',@1=N'yeni deer',@2=4
go


// Silme lemi
exec sp_executesql N'delete [dbo].[kullanicis]
where ([id] = @0)',N'@0 int',@0=4
go
7

Do rulama (Validation)
Veriler eklenirken yada dzenlenirken baz kurallar erevisinde bu ilemler gerekletirilir. Baz
alanlar bo olamaz, sadece say olabilir yada girilen deer 5 haneli olabilir gibi.. ilemlere dorulama
(validation) diyoruz. Dorulama ilemlerini modelimizin iindeki ilgili alanlara aklamalar
(Annotations) ekleyerek gerekletirebiliyoruz. Temel annotations lar
System.ComponentModel.DataAnnotations
6
snf ierisinde bulunuyor.
public class kullanici
{
public int id { get; set; }

[Required]
public string adi { get; set; }

[Required(ErrorMessage="Bu alan bo olamaz"]
public string soyadi { get; set; }

public string eposta { get; set; }

[MinLength(6,ErrorMessage="En az 6 karakterden olumaldr.")]
public string sifre { get; set; }

public DateTime kayitZamani { get; set; }
}

Eposta adresi dorulama gibi zel bir durum
7
iin ise kendi kiisel dorulamamz yazp
kullanabiliyoruz.
public class EmailAttribute : RegularExpressionAttribute
{
public EmailAttribute()
: base(@"^([0-9a-zA-Z]([-.\w]*[0-9a-zA-Z])*@([0-9a-zA-Z][-\w]*[0-9a-
zA-Z]\.)+[a-zA-Z]{2,9})$") { }
}


public class kullanici
{
[Email(ErrorMessage = "EPosta adresini ltfen doru giriniz.")]
public string eposta { get; set; }
}


Eer buraya kadar okuduysanz, rendiklerinizle ufak bir proje yapp bilginizi pekitirebilirsiniz.
lerleyen ksmlarda konunun detayna doru iniyor olacaz.


6
http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.aspx
7
zel durumlara; dosya uzants, ifre dorulama, adres format gibi eyleri rnek gsterebiliriz, eer her biri
iin ayr ayr kontrol yazmak istemiyorsanz ayr bir ktphane kullanabilirsiniz. rnek olarak
http://www.apostylee.com/dataannotationsextensions/ adresine bakabilirsiniz.
8

likiler (Relationship)
Veritaban tasarmndaki en nemli noktay hi phesiz tablolar arasnda ki ilikiler oluturuyor. Veri
btnl iin hayati nem tayan bu noktada modellerimiz iine basit bir ekilde ilikilerimizi
tanmlayabiliyoruz.
1 den oa (1 to n) liki
Senaryomuz u ekilde; bir kullancnn birden fazla yazs olabilir. Bu ilikiyi gerekletirmek iin yazi
adnda yeni bir model oluturup kullanici modeliyle ilikilendiriyoruz.
public class yazi
{
public int id { get; set; }
public string baslik { get; set; }
public string icerik { get; set; }

public virtual kullanici kullanici { get; set; }
public int kullaniciId { get; set; }
}

public class kullanici
{
public int id { get; set; }
public string adi { get; set; }
public string soyadi { get; set; }
public string eposta { get; set; }
public string sifre { get; set; }
public DateTime kayitZamani { get; set; }

public virtual ICollection<yazi> yazilar { get; set; }
}


Yukarda ki modellerimize baktmzda yazi ierisinde kullanici ve kullaniciId yi belirtip, bir yaznn bir
kullancya ait olduunu belirtiyoruz. Kullanici tarafnda ise ICollection<yazi> yazilar tanmn yapp,
bir kullancnn birden fazla yazs olacan ifade ediyoruz. Oluan iliki aada ki (ekil 2) gibi
olacaktr.

ekil 2 (Oluan tablolarn ilikisi)

imdi orm nin en zevkli ksmna sra geldi! Uzun uzun sql cmleleri yazmadan ilikili veriyi nasl
listeliyoruz bir bakalm.
9

var result = db.kullanicis.ToList();
var result2 = db.kullanicis.Include(x => x.yazilar);

Kullanclara ait yazlar yukardaki gibi iki ekilde ekebiliyoruz. Uygulamada birbirinden farksz gibi
grnsede bu iki yntem arasnda ciddi bir fark bulunuyor. Bu fark Sql Server Profiler ile
inceleimizde gryoruz.
result ileminde Lazy Loading
8
ad verilen bir durum olumaktadr. Bu durumda dng says kadar sql
ilemi gereklemektedir. Yani kullanclara ait yazlarn listelenmesi iin, kullanc says kadar sql
ilemi gerekletirilip ait olan yazlar gelmektedir. Sql server profillerde durumu izlediimizde;

ekil 3 (Lazy Loading)
Veritabannda ki 3 kullanc olduundan her kullanc iin yazlar isteniyor. Bu, ok youn olmayan
durumlarda gz ard edilebilir olsada aksi durumda ciddi bir performans kaybna yol aacaktr.




8
http://en.wikipedia.org/wiki/Lazy_loading
10

result2 de bu durumu engellemek iin yazi modelini kullanici modeline ekliyoruz (include). Bu sayede
Ado.Net Entity Lazy Loading i Eager Loading (ekil 4) e eviriyor ve daha farkl bir durum oluuyor.

ekil 4 (Eager Loading)

Eager Loading durumunda tablolar balanarak tm alanlar ekilir. Yani tek bir sorguda istenilen tm
kaytlar getirilir. Dier ynteme gre daha performansl olduunu syleyebiliriz.







11

oktan oa (n to n) liki
Bu seferki senaryomuz, birden ok yaznn birden ok kategoriye ait olmas. Bu durumu
gerekletirmek iin yukardaki modellerimizin yanna birde kategori adnda bir model ekliyor ve
gerekli deiiklikleri yapyoruz.
public class kategori
{
public int id { get; set; }
public string adi { get; set; }

public virtual ICollection<yazi> yazilar { get; set; }
public int yaziId { get; set; }
}
public class yazi
{
public int id { get; set; }
public string baslik { get; set; }
public string icerik { get; set; }

public virtual kullanici kullanici { get; set; }
public int kullaniciId { get; set; }

public ICollection<kategori> kategoriler { get; set; }
public int kategoriId { get; set; }
}

Kategori modelinin iine, birden fazla yaz olabilecei iin bir tanmlama yapyoruz, ayn tanmn
tersini yaz modeli iinde yapyoruz. Bu durum sonucunda oluan tablo yaps aadaki (ekil 5) gibi
oluyor.

ekil 5 (Oluan tablolarn ilikisi)

Yukarda ki diyagramda grld zere bizim modelimizde belirtmediimiz kategoriyazis adnda bir
tablo olumu. Bu tablo n to n ilikinin varl alglanp otomatik olarak ado.net tarafndan
oluturuluyor. likimizin kilidi de bu tablo.
12

ComplexType
yle bir senaryo dnelim, kullancmz var ve bu kullancnn adres bilgileri, profil bilgileri gibi belli
balklar altnda toplanabilen alanlar bulunuyor. Bu alanlar kmeleyip, daha derli toplu hale
getirdiimiz yaklama complextype diyoruz. rnein kod yazarken, kullancnn adres ile ilgili bir
bilgisine ihtiya duyduumuzda adres kmesi ierisinde bu bilgiyi aryoruz. Dier trl olsayd rnein
20 alan olsa 20 alan ierisinde aradm bulmaya alacak zaman kaybedecektik. Bir model zerinde
incelersek olay daha iyi anlayabiliriz.
public class kullanici {

public kullanici() {
iletisim = new iletisim();
profil = new profil();
}

public int id { get; set; }
public int adi { get; set; }
public int eposta { get; set; }

public iletisim iletisim { get; set; }
public profil profil { get; set; }

}

public class iletisim {
public string adres { get; set; }
public string sehir { get; set; }
public string sabitTelefon { get; set; }
public string cepTelefon { get; set; }
public string faks { get; set; }
}

public class profil {

public string arkaPlanRengi { get; set; }
public string arkaPlanResmi { get; set; }
public string fontRengi { get; set; }
public string avatar { get; set; }
}

Kullanc modeline baktmzda 3 modelmi gibi grnyor fakat iletiim ve profil snflar
kmelediimiz bilgileri tutmamza olanak salyor. Yani bizim complextype larmz bunlar ;) Bu
modelden oluan tablo aadaki (ekil 6) gibi oluyor. Grld zere alanlar complextype adn n
ek olarak almlar (iletiim_adres) bunun sebebi farkl kmelerde ayn alan adlarnn oluturaca
karkl ve hatalar nlemek.
13


ekil 6 (ComplexType)

Kod yazarken bize salad fayday aadaki resimde (ekil 7) grebiliriz.

ekil 7 (ComplexType Avantaj)

Eer ComplexType kullanmasaydk, hangi bilginin nerede olduunu arayacaktk fakat bu ekilde hangi
bilgi nerde olabiliri rahatlkla anlayp, bilgiye hemen ulaabiliyoruz. Onlarca alana sahip bir modelde
bu yntemin iimizi bir hayli kolaylatrdn rahatlkla syleyebiliriz.
14

Ado.Net Fluent Api
Fluent Api
9
en kaba tabirle kod tarafyla sql tarafnda ki mapping ilemlerini dzenlememize olanak
sayalan bir api. rnein model snfmzdaki bir alann ad adi iken veritabannda bunun name olmas
gerekebilir yada kurduumuz bir ilikinin adnn deimesi gerekebilir. Bu ve benzeri dzenlemeleri
fluent api sayesinde gerekletiriyoruz. Modelimiz zerinde fluent api kullanmna bakacak olursak;
[Table("user")]
public class kullanici
{
[Key]
public int id { get; set; }

[Column("name")]
public string adi { get; set; }
public string soyadi { get; set; }
public string eposta { get; set; }
public string sifre { get; set; }
public DateTime kayitZamani { get; set; }
}

Bu durumda veritabannda oluan tablonun ad user, modelde adi olan alann name olarak
olutuunu grebiliriz. Fluent Api esas olarak context iine yazacamz OnModelCreating
methodunun iinde kullanlyor, burada ki ama model oluturulurken yaplacak ilemlerin tek bir
yerde toplanmas. Yukarda ki rnei imdide context iinde gerekletirelim.
public class adoNetKitapContext : DbContext
{
public DbSet<kullanici> kullanicis { get; set; }

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<kullanici>().ToTable("user");
modelBuilder.Entity<kullanici>().Property(x => x.adi).HasColumnName("name");
}
}


Fluent apiyi elimizden geldiince yaymadan context iinde kullanmamzda fayda var. Sebebi ise bu
ilemlerin tek bir at altnda toplanmas ve bir problem yada gncelleme olaca zaman
deiikliklerin buradan yaplacak olmas.


9
Fluent Api rneklerine http://blogs.msdn.com/b/adonet/archive/2010/12/14/ef-feature-ctp5-fluent-api-
samples.aspx adresinden bakabilirsiniz.
15

pular
Where
var result1 = context.kullanicis.Where(x=>x.id > 5);
var result2 = context.kullanicis.Where(x => x.id > 10 && x.adi == "ahmet");
var result3 = context.kullanicis.Where(x => x.adi.Contains("ahmet"));

result1 bildiimiz where ilemi, id si 5 den byk kaytlar getiriyor.
result2 yine bildiimiz where ilemi, id si 10 dan byk adi ahmet olan kaytlar getiriyor.
result3 inde ahmet geen kaytlar listeliyoruz. Contains ile veritabannda arama ilemini yapyoruz,
yani sql deki like n iini yapyor.
Select
var result6 = context.kullanicis.Select(x => new { ID = x.id, ADI = x.adi });

Baz durumlarda modelimizdeki tm alanlara ihtiya duymayz, select ile istediimiz alanlar
belirtebiliyoruz. Yukarda ki ilemin sql de ki karl; select id as ID, adi as ADI from kullanicis
OrderBy
var result4 = context.kullanicis.OrderByDescending(x => x.id);
var result5 = context.kullanicis
.OrderBy(x => x.id).ThenByDescending(x=>x.kayitZamani);


result4 de id si bykten ke doru listeliyoruz. Eer direk OrderBy (x => x.id); deseydik id si
kkten bye doru sralanacakt.
result5 burada ise id si kkten bye ve kayitzamani bykten ke doru sralama ilemini
yapyoruz.
Top, Max, Min
var result7 = context.kullanicis.Take(10);
var result9 = context.kullanicis.Max(x => x.id);
var result10 = context.kullanicis.Min(x => x.id);

result7 10 kayd listeler. context.kullanicis.OrderByDescending(x => x.id).Take(10); eklinde ise en son
girilen 10 kayd listeleyebiliriz.
result9 en byk id deerini dndrr.
result10 en kk id deerini dndrr.


16

SqlQuery, ExecuteSqlCommand
var result8 = context.Database.SqlQuery<kullanici>("Select * from kullanici");
context.Database.ExecuteSqlCommand("update from kullanici set adi = 'test' ");


result8 de kendi sql sorgumuzu direk yazp kullanabiliyoruz, burada dikkat edilecek husus
veritabanndan dnen alanlarn trleri ve isimleri yklenecek snftakilerle birebir ayn olmaldr. Bu
yntemi veritabannda ki bir view dan kaytlar ekmek iin kullanabiliriz.
Direk sql komutu altrmak iin ExeCuteSqlCommand zelliini kullanabiliyoruz. Bu zellik baz
durumlarda hayati nem tayabiliyor.
Son So z
Ado.Net Entity her yeni versiyonda biraz daha iyiletirilen bir orm arac. zellikle web uygulamas
gelitirirken MVC3 ile birlikte bize sunduu kolaylklar gz ard edilecek gibi deil, gnlmde Mvc3
ile birlikte nasl kullanldna dair bilgileri bulabilirsiniz.
Umarm yararl bir dokman olmutur. Gelen istekler dorultusunda bu dokman gncellemeye
alacam. Tm gzellikler sizinle olsun.





Abdullah URAKAN
Web Developer




apoStyLEE.com
twitter.com/apoStyLEE

You might also like