POCO(Plain Old CLR Objects) Nedir?

Entity Framework Ado.Net Data Model’de yer alan varlık(entity)larımız için kendi sınıflarımızı yazabilmemize destek verir. Bu yapıda varlıklar herhangi bir sınıftan türetilmez, herhangi bir interface’i implemente etmez, veri en sade şekilde tutulur.Böylece projemizi otomatik olarak oluşturulan modelle birlikte gelen birçok koddan kurtarıp, daha basit bir model oluşmasını sağlayabiliriz.

1- POCO Nesnelerinin Oluşturulması

POCO ile modelimizi oluşturmak için öncelikle projemize bir ADO.Net Entity Data Model ekliyoruz. Bunun için projeye sağ tıklayıp Add New Item -> Ado.Net Entity Data Model seçiyoruz. Karşımıza bir Wizard çıkıyor, burada Generate from database deyip ilerliyoruz.Çıkan ekranda veritabanını seçiyoruz. (Ben örneğimizde Misrosoft’un örnek database’lerinden biri olan AdventureWorks’u kullandım.) Sonraki ekranda veritabanında bulunan tablo, stored procedure ve view’ların listesini görebiliriz, Örneği küçük tutmak adına Tables sekmesinden sadece ProductCategory tablosunu seçtim.

POCO nesnelerimizi oluşturabilmek için öncelikle modelimizin Properties kısmındaki CodeGenerationStrategy özelliğinin değerini None yapıyoruz. Böylece modelimizin Designer kısmında model üzerindeki nesnelerimiz ile ilgili kodların olması gerekirken aşağıdaki gibi bir bilgilendirme görürüz.

// Default code generation is disabled for model ‘D:\Çalışmalarım\EF\POCONedir\POCONedir\AdventureWorks.edmx’.

// To enable default code generation, change the value of the ‘Code Generation Strategy’ designer

// property to an alternate value. This property is available in the Properties Window when the model is

// open in the designer.

Bu aşamada öncelikle veritabanındaki tablomuza karşılık gelen sınıfımızı ve sonrasında Context nesnemizi oluşturacağız.

public class ProductCategory

{

public const string EntitySetName = “ProductCategory”;

public int ProductCategoryID { get; set; }

public string Name { get; set; }

public Guid rowguid { get; set; }

public DateTime ModifiedDate { get; set; }

}

Burada dikkat etmemiz gereken nokta; kendi yazdığımız ProductCategory sınıfının adının ve özellik adlarının modeldeki isimlerle birebir aynı olması gerektiğidir. Farklı isimlendirmeler yapmak isterseniz bu durumda çeşitli ayarlamalar yapmanız gerekir.

public class AdventureWorksContext : ObjectContext // Modelimizi ve sınıflarımızı barındıracak Context sınıfımızı yazıyoruz.

Entity Framework ile otomatik oluşturulan Context, ObjectContext sınıfından kalıtılır. Bunu bir EF oluşturduğunuzda Designer.cs’ine bakarak da görebilirsiniz.

AdventureWorksContext sınıfımızda ProductCategory sınıfımızı barındıran ObjectSet tipinden bir özelliğimizin olması gerekiyor. Bunu sağlamak için de aşağıdaki tanımlamaları yapıyoruz.

private ObjectSet<ProductCategory> _productCategory;

 

public ObjectSet<ProductCategory> ProductCategory

{

get { return _productCategory ?? (_productCategory = CreateObjectSet<ProductCategory>()); }

}

CreateObjectSet<T>() metodu ile yaptığımız örnekleme işlemini Context’imizin Constructor’ında da yapabiliriz. Şuan sadece tek bir tablo üzerinde çalışıyoruz o yüzden bu işlemi Constructor’da yapmak performans ve bellek kullanımı konusunda sorun olmaz; ama gerçek hayatta modellerimiz bir çok tablodan oluşacak ve bu durumda Constructor’da gereksiz yere yaptığımız örnekleme çok da optimum bir işlem olmayacaktır. Bu nedenle en makul yöntem ObjectSet’imizi ihtiyaç duyduğumuzda oluşturmak.

Bu aşamada Context’imiz hala hangi bağlantı cümleciğini kullandığını bilmiyor. O nedenle Constructor’da bunu bildirmemiz gerekiyor.

public AdventureWorksContext()

: base(“name=AdventureWorksEntities”, “AdventureWorksEntities”)

{

 

}

Buradaki ilk parametre entity data modelimizi oluştururken App.Config dosyasına kaydettiğimiz bağlantı cümlesi(ConnectionString)’nin adı, ikinci parametre ise Entity Container’ın adı() Bu adı Modele sağ tıklayıp Model Browser dediğimizde açılan pencereden AdventureWorksModel’in altındaki EntityContainer’dan öğrenebilirsiniz.

2- POCO Nesnelerinde CRUD İşlemleri
Veriye erişimi sağlamak için ProductCategoryDataAccess adında yeni bir sınıf oluşturuyoruz ve kodlarımızı bu sınıf içine yazıyoruz.

  • Kayıt Ekleme

public ProductCategory Create(ProductCategory category)

{

using (AdventureWorksContext ctx = new AdventureWorksContext())

{

ctx.ProductCategory.AddObject(category);

ctx.SaveChanges();

}

return category;

}

Dikkat edecek olursanız ctx.ProductCategory aslında bizim ObjectSet<ProductCategory> özelliğimiz.  Burada SaveChanges() metodunu çağırmadığımız sürece veritabanında herhangi bir işlem gerçekleştirilmez.

  • Kayıt Güncelleme

public ProductCategory Update(ProductCategory category)

{

EntityKey key = null;

 

using (AdventureWorksContext ctx = new AdventureWorksContext())

{

//EntitySetBase itemEs = ctx.GetEntitySet(category);

//key = ctx.CreateEntityKey(itemEs.Name, category);

key = ctx.CreateEntityKey(ProductCategory.EntitySetName, category);

ctx.GetObjectByKey(key);

ctx.ApplyCurrentValues(ProductCategory.EntitySetName, category);

ctx.SaveChanges();

}

return category;

}

Context’teki ProductCategory sınıfımızın Model’deki hangi tabloya karşılık geldiğini bulmak için Context sınıfına aşağıdaki gibi GetEntitySet() adında bir metot yazabilir ya da ProductCategory sınıfımızda

public const string EntitySetName = “ProductCategory”;

şeklinde tanımlayıp direk kullanabiliriz.

public EntitySetBase GetEntitySet(Object entityType)

{

EntityContainer container = this.MetadataWorkspace.GetEntityContainer(this.DefaultContainerName, DataSpace.CSpace);

EntitySetBase entitySet = container.BaseEntitySets.SingleOrDefault(es => es.ElementType.Name == entityType.GetType().Name);

return entitySet;

}

  • Kayıt Silme

public void Delete(ProductCategory category)

{

using (AdventureWorksContext ctx = new AdventureWorksContext())

{

ctx.ProductCategory.Attach(category);

ctx.ProductCategory.DeleteObject(category);

ctx.SaveChanges();

}

}

Öncelikle sileceğimiz category nesnesini Context’imize ekliyoruz. DeleteObject() metodunu çağırdığımızda aslında silme işlemi gerçekleşmiyor,sadece nesnemiz silinecek olarak işaretleniyor, SaveChanges() dediğimizde siliniyor.

  • Kayıt Getirme

public List<ProductCategory> GetProductCategories()

{

List<ProductCategory> list = null;

using (AdventureWorksContext ctx = new AdventureWorksContext())

{

list = ctx.ProductCategory.ToList();

}

return list;

}

Son olarak da uygulamayı test edelim.WindowsForms uygulamamıza ListBox atıp aşağıdaki metodu yazalım.Yazdığımız metodu Constructor’da çağırdığımızda aşağıdaki gibi bir ekran görüntüsü alırız.

void Bind_lstCategory()

{

ProductCategoryDataAccess da = new ProductCategoryDataAccess();

lstCategory.DataSource = da.GetProductCategories();

lstCategory.DisplayMember = “Name”;

lstCategory.ValueMember = “ProductCategoryID”;

}

Kaynaklar:
• Entity Framework 4.0 Recipes / Larry Tenny, Zeeshan Hirani

Reklamlar

4 thoughts on “POCO(Plain Old CLR Objects) Nedir?

  1. Ben almanyadan sevgi, gercekten cok guzel bir blog, eger twitter veya facebook sayfasi varsa hemen
    ekliycegim.

    1. İlk paragrafta açıklıyor, poco’nun c# için kısa ve basit anlatımı bu. POCO mimarisinin ne olduğunu anlatmak amaçlanmıyor yazıda, C# Entity Framework üzerinde uygulamasının nasıl yapılabileceğini anlatabilmek amaç

Bir Cevap Yazın

Aşağıya bilgilerinizi girin veya oturum açmak için bir simgeye tıklayın:

WordPress.com Logosu

WordPress.com hesabınızı kullanarak yorum yapıyorsunuz. Çıkış  Yap / Değiştir )

Twitter resmi

Twitter hesabınızı kullanarak yorum yapıyorsunuz. Çıkış  Yap / Değiştir )

Facebook fotoğrafı

Facebook hesabınızı kullanarak yorum yapıyorsunuz. Çıkış  Yap / Değiştir )

Google+ fotoğrafı

Google+ hesabınızı kullanarak yorum yapıyorsunuz. Çıkış  Yap / Değiştir )

Connecting to %s