Makale Özeti

Merhabalar. Herkesin bildiği gibi EntityFramework ile database first yöntemiyle geliştirdiğimiz uygulamalarda her ne kadar DataAccess katmanı yazsak bile Entity nesnelerimiz DataAccess katmanında kalıyordu. Bunları ayırarak tamamen farklı bir ortak Entity katmanında toplamaya çalışıyoruz.

Makale

 

Entity Framework ile uygulama geliştirirken bir çok yerde okuyap görebileceğimiz yöntemler var. Code First, Model First, Database First gibi. Ben kişisel olarak database first çalışmayı doğru bulduğumu söyleyebilirim.  Peki Entity classları oluşturup, uygulamanın genelinde DAL katmanını referans etmeksizin Entity classları kullanabilsek daha esnek (flexible) bir uygulama geliştirebilirdik belki. Bence denemeye değer... Şöyle düşünelim.

Çoğumuz için anlamlı olmayan bir çok şekil çizmek kolay tabi ki. Ama hangisi ne işe yarıyor şimdi bu burdan nereye gitti falan diye düşünmek yerine doğrudan herkesin anlayabileceği dilden anlatmak bence daha kolay...

Amaç: Arayüz katmanından girilen bilgileri bir iş katmanına aktarmak ve gerekiyorsa bu katmanda iş mantığını yürütüp veritabanına daha sonra aktarmak.

Neden Gerekli? Girilen bilgileri doğrumamamız gerekebilir, Hesaplar yapmamız gerekebilir, ayıklamamız gerekebilir.  Bu işlemler çok karışık algoritmalara bile tabi tutuluyor olabilir. Şimdi bunları neden başka bir katmanda yazmamız gerkekiyor gayet aynı yerde de yazabiliriz diye düşünenler için doğru soru? Tekrar kullanmanız gerekirse baştan mı yazardınız? Muhtemelen yazmaz kopyalayıp ufak düzenlemeler ile kullanırdınız. Ama aynı kodu iki farklı uygulama için tekrar derlerdiniz.

Katmanlara bölerek tekrar kullanmanız gerektiğinde ilgili parametreleri sağlayarak aynı işi tekrar yaptırabiliyor olabiliriz.

Bu kadar laf kalabalığı bence  de yeter.
Bir uygulama açalım ve laf salatası yaptığımız işi yapmayı deneyelim bakalım ne kadar başarılı olabileceğiz.

4 uygulama ekliyoruz. Bir tanesi arayüz katmanınız olacak. Buradan girilen bilgiler her ne suretle olursa olsun buyuk harfe çevrilerek veritabanına kaydedilecek. Bizim iş mantığımız bu şimdilik.

 

İkinci adım, ihtiyacımız olan veritabanını oluşturmak veya hazır örnek veritabanlarından kullanabiliriz. Ben AdventureWorks kullanmayı tercih ediyorum. Aşağıdaki gibi iki tablo bence örnek için bize yeter.

 

App.DAL katmanı altına bir Project->Add New Item menüsünü kullanarak Data Templates altından ADO.NET Entity Data Model nesnesi ekliyoruz.

 

Tabi söz konusu uygulama Visual Stuido olunca Sizi bir sihirbazın karşılaması işten bile değil.

Bir sonraki adım artık veritabanında bulunan nesnelerimiz için Entity nesnelerini oluşturmak.

 

Tabi bu adımı ilerlediğinizde size açık bağlantıları gösterecek ve hangisini seçmek istediğinizi soracak. Bende aktif bir bağlantı yok haliyle yeniden oluşturacağım. Sizin açık bir bağlantınız varsa bunu kullanabilirsiniz.

 

Tam olarak ihtiyacımız olan görüntü bu.  Sonraki adım ise hangi nesneleri veritabanı erişiminde Entitiy olarak kullanacağımızı soran ekran. Ben aşağıdaki gibi bir ekran oluşturuyorum. Böylecek örnek niyetiyle oluşturduğum iki tabloyu Entitiy nesnesi olarak (Aslında bunlar Poco*) oluşturuyorum.

 

Finish butonuna bastığımızda elde ettiğimiz görüntü garip ama işte bu.

 

Veritaabanı tasarımıza benziyor gibi. Ne dersiniz?

Şimdi biz Visual Studio Code Generator’unun neler yazdığını ben biraz merak edip içini açıp bakma gereksinimi hissettim.

 

Sanki biraz... kapalı? Evet ama biz bununla ilgilenmiyoruz aslında. Şimdi bizim asıl konumuz App.DAL içinde bulunan Entity nesnelerinin App.Entity içinde nasıl oluşturulacağını merak ediyorum. Böylece aslında doğrudan DAL katmanını referans etmeden bir Businnes Logic katmanı üzerinden işlemlerimizi yürütebiliyor olacağız. Bunun için Entity Framework POCO Generator isimli bir online template kullanıyor olacağız. NuGet Manager’dan yükleyebilirsiniz.  App.DAL projesi üzerine gelerek Project ->Add New Item Seçiyoruz.

 

Eklediğimiz anda bir sürü hata verdi Visual Studio bize...

 

Bir dosyayı bulamıyor ? Acaba hangisi ? Model.tt dosyasına çift tıklayarak için bir açalım bakalım.

 

Evet böyle bir dosya yok bizim projemizde.  Biz bunun için .edmx dosyasını belirtiyoruz.  $edmxInputFile$ yerine “../App.DAL/AdventureWorks.edmx” yazarak ihtiyacımız olan Entity nesnelerini oluşturuyoruz. Dosyayı kaydettiğimiz anda Model.tt dosyası altına aşağıdaki gibi nesnelerin oluştuğunu görmemiz gerek. Görmediysek bir noktada hata yapıyoruz anlamına gelir.

 

Tabi ki sadece Model.tt dosyası için değil aynı zamanda Model.Context.tt dosyası için de yapmamız gerek.

 

Bu alanıda güncelledikten sonra Model.Context.tt dosyasının içerisinde bulunan .cs dosyasının içinde görmemiz gereken dosya bu.

 

Şimdi bizim App.DAL içindeki Model.tt  dosyasını sürükle bırak yöntemi ile App.Entity içine taşıyoruz. Tabi bu işlem kopyalama olarak gerçekleşecek ancak bizim App.DAL içindeki dosyayı silelim artık buna ihtiyacımız yok bence. Zaten altı çizgili alanda da göreceğiniz üzere biz App.Entity projesini referanslara ekledik. Product ve ProductModel sınıflarını artık referanslara eklediğimiz herhangi bir namespace altında arayıp bulacaktır. Ancak Model.tt altında oluşan sınıflarımızın Namespace’leri App.DAL olarak kaldı. Bunu App.Entity olarak değiştiriyor olmamız gerek.

 

AdventureWorks.edmx altında bulunan AdventureWorks.Designer.cs dosyasına da ihtiyacımız yok. Zaten Model.Context.tt bizim işimizi görecektir. Amacımız Entity classları ayırarak başka proje altına taşımaktı. Zaten biz bunu gayet güzel bir şekilde başardık.

Şimdi ihtiyacımız olan aşağıdaki modele uygun şekilde Referanslarımızı eklemek. İşlerimizi gruplamıştık bu durumda Entity işlemleri yapacağımız sınıflardan App.BL içine System.Data.Entity assembly’sini referanslara ekliyoruz. Tabi Businnes Layer kullanım amacımız App.DAL’ı kullanarak veri tabanı işlemlerini yapmak. Bu nedenle App.DAL ve App.Entity  projelerimizi de referanslara ekliyoruz.

       


Şimdi referanslarımızı altı çizgili hallere getireceğiz ki  entity’ler ile işlem yaptığımız yerlerde sorun yaşamayalım.

Dikkatinizi çektiyse GUI üzerinde App.DAL katmanı için referans oluşturmadık. Ama unutmadan App.DAL katmanı içindeki  ConnectionStrings tag’ini GUI katmanında bulunan Web Config altına taşımamız gerekiyor. Sonuçta bizim uygulamamız buradan çalışacak ve bağlantı cümlesini burada arayacak.

Şimdi biz veritabanından bir takım bilgileri çekip ekranda görüntülemeye çalışalım.App.BL projesine bir sınıf ekliyoruz. Ismini de ProductManager olarak ayarlıyoruz. İçeriği aşağıdaki gibi.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace App.BL
{
    public class ProductManager
    {
        public List<Entity.Product> GetProductList()
        {
            DAL.Entities ent = new DAL.Entities();
            return ent.Products.ToList();
        }

        public int InsertProduct(Entity.Product product)
        {
            DAL.Entities ent = new DAL.Entities();
            ent.Products.AddObject(product);
            ent.SaveChanges();
            return product.ProductID;
        } 
    }
}

Manager sınıfımızı yazdığımıza göre artık bu sınıfı kullanarak GUI’den bazı işlemler yapalım. Default.aspx içine bir GridView nesnesi ekledim. İsimlendirme ile vakit kaybetmek istemiyorum ama siz mutlaka anlaşılır bir isim verin =)

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <asp:GridView ID="GridView1" runat="server" >
          
        </asp:GridView>
    </div>
    </form>
</body>
</html>

 

Şimdi Default.aspx dosyamızın codebehind tarafına Manager sınıfını çağıran kodu ekliyoruz.

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace App.GUI
{
    public partial class Default : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            App.BL.ProductManager manager = new BL.ProductManager();
            GridView1.DataSource = manager.GetProductList();
            GridView1.DataBind();
        }
    }
}

Bu şekilde manager sınıfımızı genişletebiliriz. Aslında bir IManager  interface’i yazıp standart metodları uygulayabiliriz bile gerisi sizin yoğurt yiyişinize kalmış.

 Sanki videosunu çeksek daha güzel olacak gibi ama sanırım ki bu şekilde de yapmak istediğimiz her şeyi yapabileceğiz.

Son olarak bağımlılık grafiği paylaşmak istiyorum bir çoğumuz için saçma sapan gelsede çok büyük anlam ifade edebilecek bir grafik aslında.

 

 

Bu demek oluyor ki biz GUI kısmını değiştirip bir Mobile Application yada Windows Application yapacak olsak sadece GUI katmanını yazarsak projede çok fazla değişiklik yapmamıza gerek kalmayacak.

 

Ertuğrul KARA.

Yazılım Uzmanı.

 

Uygulama Kodlarına aşağıdaki bağlantıdan ulaşabilirsiniz.

EntityFrameworkWithPoco.zip