Veritabanı işlemlerinden insert,update ve delete gibi işlemleri yaparken her tablo için ayrı ayrı kod yazmamız gerekir. Yani, örneğin 20-25 tane tablomuz olsun, biz bu 20-25 tane tablomuz için her birine insert kodlarını, update kodlarını ve delete kodlarını yazmamız gerekiyor. Fakat bu işlemler çok fazla iş yükü barındırır ve her yaptığımız işlem için bağlantı açıp kapatmamız lazımdı. Repository Pattern ile hem kod kalabalığından kurtulup hemde iş yükünü azaltarak, ekle hata payını en aza indirgeyerek daha temiz kod yazabiliriz.
Öncelikle bir sınıf oluşturup işlemlerimize başlayalım. Kütüphaneleri eklemeyi unutmayalım !
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Data; using System.Linq.Expressions; using System.Data.Entity; using System.Data.Entity.Infrastructure; using MvcApplication1.Models; //Data yani Entity Model'in olduğu kısım using System.Data.Entity.Core.Objects; namespace MvcApplication1.ALLProcess { public class Repository<T> where T : class { IObjectContextAdapter _context; IObjectSet<T> _objectSet; public Repository() //Constructor { _context = new luxwatch_databaseEntities(); //benim kullandığım entity _objectSet = _context.ObjectContext.CreateObjectSet<T>(); } public IQueryable<T> AsQueryable() { return _objectSet; } public T First(Expression<Func<T, bool>> where) //(İlk Eleman) { return _objectSet.First(where); } public IEnumerable<T> Find(Expression<Func<T, bool>> where) { return _objectSet.Where(where); } public void Delete(T entity) (Silme) { _objectSet.DeleteObject(entity); _context.ObjectContext.SaveChanges(); } public bool Add(T entity) // (Ekleme) { _objectSet.AddObject(entity); _context.ObjectContext.SaveChanges(); return true; } public void Attach(T entity) // (Güncelleme) { _objectSet.Attach(entity); _context.ObjectContext.SaveChanges(); } public List<T> getList() {//all the elements (tüm elemanlar) List<T> _list = _objectSet.ToList(); return _list; } // According to order by descending query (örneğin tarihe göre ürün getirme) public List<T> Listele2<F>(Expression<Func<T, F>> where) { return _objectSet.OrderByDescending(where).ToList(); } //According to query (Sorguya Göre) public List<T> SorguyaGoreListele(Expression<Func<T, bool>> where) { return _objectSet.Where(where).ToList(); } } }
Yukarıdaki “using MvcApplication1.Models;” adlı namespace’imiz projemizin data katmanından gelmektedir. Görüldüğü üzere tek bir sınıf üzerinden istediğimiz tabloya erişebileceğiz. Add, getList, Delete, Attach(Update) ve bir çok metotlarımız bulunmaktadır. Siz isterseniz kendi metodunuzu yazıp, onu tekrar tekrar istediğiniz tablo için çağırabilirsiniz. Şimdi bir örnek üzerinde daha kolay anlaşılacaktır.
Ürün ekleme sayfasında şu kodları yazmamız gerekir. Örneğin;
Repository<Product> _product = new Repository<Product>(); Product pd = new Product(); pd.product_name = productName; pd.product_price = Convert.ToDecimal(productPrice); pd.product_describe = productDescribe; pd.product_photo = dosyaYolu; pd.product_datetime = System.DateTime.Now; pd.product_discount = Convert.ToInt16(productDiscount); pd.category_id = Convert.ToInt16(catID); pd.brand_id = Convert.ToInt16(brandID); _product.Add(pd);
İşlem bu kadar basittir. Repository<Product> yazdığımız anda zaten hangi tabloya veri ekleneceğini sınıf sayesinde direk anlıyor kodlarımız.
Başka bir örnek, mesela Ürün_Detay sayfasına girdiğimizde tıklanılan ürünün gelmesini,gösterilmesini istiyorsak;
public ActionResult Detail(int id) { Repository<Product> getproduct = new Repository<Product>(); getproduct.SorguyaGoreListele(i => i.product_id == id).FirstOrDefault(); }
Ürün silmek istiyorsak;
public ActionResult ProductDelete(int id) { Repository<Product> _product = new Repository<Product>(); Product pd = _product.SorguyaGoreListele(x => x.product_id == id).FirstOrDefault(); _product.Delete(pd); }
Product yerine Kategorilerden bir veri silmek isterseniz Repository<Categories> yaparsınız, veya üye silmek isterseniz Repository<Members> yaparsınız, istediğiniz tablo ismini yazabilirsiniz. Aslında siz sınıfa gönderdiğiniz tablonun ismini bir Type olarak gönderiyorsunuz, gönderdiğiniz anda neyin ne olduğunu anlıyor 🙂
Bana kalırsa çok büyük bir nimet, ben bu Pattern ile tanışmadan evvel her bir tablo için amele gibi kod yazıyordum 😀