|
Asp.Net MVC Framework - II |
|
Gönderiliyor lütfen bekleyin... |
|
|
Bir önceki makalemizde
MVC Framework ‘ün ne işe yaradığını, nasıl bir mimari düşünce içersinde çalıştığını
ve bu mimarinin bize katkılarının neler olduğuna değinmeye çalıştık. Sonrasında
ise ilk MVC uygulamamızı açarak bize hazır olarak oluşturulan klasörlerin sınıfların
ve web servis kontrollerine göz atmaya çalıştık. Daha sonrasında ise View ve
Controller içeriklerini kontrol ederek işlemlerimizi tamamlamış olduk.
View ve Controller kavramlarını inceledik fakat bir diğer katman olan Modele
yalnızca isim olarak değindik ve ne işe yaradığından bahsetmiştik. Bu makalemizde
ise MVC Framework ‘te veri tabanı işlemlerimizi yapmamıza yarayacak olan Model
katmanını incelemeye çalışacağız.
Model katmanını incelerken LinQ to
SQL ile sorgularımızı daha nesnesel bir şekilde kullanırken
veri tabanı olarak da SQL SERVER 2005 ile birlikte gelen örnek veri tabanlarından
Adventure Work 'u kullanacağız.
Yazımızın ayrıntılarına
girmeden önce isterseniz tekrardan Modelin ne olduğunu hatırlayalım.
Model: Model genellikle veri tabanı işlemlerimizi yani
işlerimizi( business ) yaptığımız yapıdır. Veri tabanımız üzerinde yapılabilecek
sorgularımızı burada belirler ve Controller ’ı atamamızı sağlarız. Bu sayede
veri tabanımıza dışarıdan daha kolay erişebilir ve çeşitli metotlarla daha kolay
idare/müdahale edilebilir hale getirir.
Şimdi model katmanını incelemeye
başlayabiliriz. Model veri tabanı işlemlerinin yapıldığı bir katman olduğundan
ötürü bizde bunu örnek üzerinden anlatmaya çalışacağız.
Uygulamamıza
başlarken File-->New-->Project adımlarını izleyerek ASP.NET MVC Web Application
seçeneğini seçiyoruz. Projemizin ismini de AdventureWorkMerhaba
olarak belirledikten sonra projeyi tamam butonuna basarak uygulamamızı
oluşturuyoruz.
Veri
tabanımızı uygulamamıza ekleyebilmek için Server Explorer bölümünden Data Connections
‘ın üzerinde sağa tıklayarak Add Connection seçeneğini tıklarız.
Karşımıza Server adını
ve veri tabanı ismini girmemizi isteyen bir ekran gelecektir. Bu bölümde de
server ismini (eğer SQLExpress kullanıyorsanız server ismi = sqlexpress ‘tir)
girdikten sonra database isminin olduğu bölümün içeriği otomatik olarak bizim
üzerinde çalışmakta olduğumuz veri tabanları ile doldurulur. Bizde oradan AdventureWork
‘ü seçerek tamam dediğimizde artık uygulamamızın bir veri tabanı oluyor.
Uygulamamızda kullanacak
olduğumuz veri tabanına ait sorgularımızı model katmanının içerisinde oluşturacağımızdan
ve bu sorguları da LinQ to SQL yardımı ile yapacağımızdan bahsetmiştik. Bu sebepten
ötürü Model klasörümüzün içerisine gerekli olan sınıfı eklememiz için model
klasörünün üzerine sağa tıklayarak Add-->NewItem basamaklarını uygulaya biliriz.
Yeni öğe ekleme seçeneğinin
içeriği açıldığı zaman karşımıza her zamankinden farklı öğeler karşılamaktadır.
Karşılaşılan öğeler MVC ile ilgili olanlardır. Bunların listede yer almasının
başlıca sebebi MVC Framework ‘ü kurmamızdır. Eğer bu Framework ‘ü kurmadan MVC
uygulaması yapmaya çalışsaydık daha önceki zamanlarda olduğu gibi bu öğelerin
hazırlanması içinde uzunca bir zaman ayırmamız gerekecekti.
Bu öğeleri bir kenara bırakırsak
bizim işimize yarayacak olan sınıfı eklemek için karşımızda listeden
LinQ to SQL Classes ‘ı bularak ismini AdventureWork olarak
belirledikten sonra tamamı seçerek uygulamamıza ekliyoruz.
Eklediğimiz zaman dikkatimizi
çeken birkaç nokta oluyor. Bunlardan birinci referanslar bölümünde yeni eklenen
referansların olması. Bu referanslar LinQ to SQL ile ilgili sınıfları ve özellikleri
kullanmamız için gereklidir.
İkincisi ve en önemlisi
olanda *.dbml uzantılı bir dosya oluşturuyor. DBML
database Markup Language anlamına gelen ve yardımcı
veri olarak kullanılmakta olan bir sınıftır.
AdventureWork.dbml
‘imizi oluşturduğumuzda bizden uygulamamızdaki veri tabanına ilişkin tabloları
eklememizi beklemeye başlayacaktır. Şimdi de bu işlemleri nasıl yapacağımıza
değinmeye çalışalım.
Daha önceden eklemiş olduğumuz veri tabanının tablolarından
ihtiyacımız olanları Object Relationel Designer (ORD) yazan yere sürükleyip
bırakıyoruz. Biz bu uygulama için tablolardan Product, ProductOrderDetail ve
ProductCategory ‘i ORD ‘ye sürükleyerek tabloların ve bu tablolara ait özelliklerin
ekran gözükmesini sağlamış oluruz. Ayrıca bu tablolar arasında herhangi bir
ilişki var ise onlarda otomatik olarak ekranda oluşturulacaktır.
İlişkileri oluşmuş olan tablolarımızı
kaydedip kapattıktan sonra dmbl dosyamızın arka planında oluşan kodlarına göz
atalım. Bakalım veri tabanı tablolarımız ve bu tablolarımıza ilişkin özellikler
nasıl oluşmuş.
Oluşmuş olan kodları aşağıdaki tablonun içersinde bulabilirsiniz.
Fakat verecek olduğumuz kod bloğu oluşturulmuş olan kodun tümü değildir. Bunun
sebebi ise yaklaşık 1250 satır kodun oluşturulmasıdır.
Kodları vermeden
önce daha önceden asp.net, Java veya başka bir dille oluşturmuş olduğumuz model
sınıflarında tek tek tablolarda yer alan özellikleri tanıtmak zorunda kalır
ve bu özelliklere ilişkin verilen/alınan değerlerini de ayrıca elimiz yardımı
ile girmek zorunda kalırdık. Bu işlem esnasında birçok sorunla da karşılaşmamız
mümkündü. Biraz önce uygulamış olduğumuz yöntem sayesinde bize zaman kaybettiren
birçok kodu yazmaktan kurtulabiliriz. Fakat aklınıza güvenli mi veya doğru mu
oluşturuldu biçiminde sorular takılabilir. Bunun cevabı eper ekstra işlem yapmayacaksak
doğru ve güvenilirdir. Fakat tablolar arası join gibi işlemler yapmak istersek
tabii ki de otomatik olarak oluşturulan kodu düzenlememiz gerekecektir.
Join işlemlerini neden örnek verdiğimize gelirse. SQL de join işlemleri
birçok tablodan alınan değerler sonucunda bize sonuçlar döndürebilmekteydi.
Bu tür işlemleri sql kodları ile yapmak kolaydı. Çünkü herhangi bir sınıftan
veya başka bir yerden özellik çağırmadan sql kodları ile işlemlerimizi yapabiliyorduk.
Fakat Model katmanında tabloları ayrı ayrı parçalı sınıflar biçiminde tuttuğumuz
için ve benzer isimli sütunlarda oluşabileceği için sorgulama işlemlerimizde
sorunlar çıkabilmekteydi. Bu sorunların kaldırılması içinde model katmanda oluşturmuş
olduğumuz sınıflara o kullanacak olduğumuz sütunlara ilişkin özellikleri tanımlamalı
ve işlemlerimize öyle devam etmeliydik. İşte bizimde şu anda oluşturmuş olduğumuz
dbml ‘in arka planındaki kodlar en basit biçimiyle oluşturulmaktadır. Bizler
onu özelleştirmek istersek buna imkan tanınmıştır.
C#
[System.Data.Linq.Mapping.DatabaseAttribute(Name="AdventureWorks")]
public partial class AdventureWorkDataContext : System.Data.Linq.DataContext
{
private static System.Data.Linq.Mapping.MappingSource
mappingSource = new AttributeMappingSource();
#region Extensibility
Method Definitions //SQL ile yapılabilecek işlemler otomatik
olarak tanımlandı partial void OnCreated(); partial void
InsertProduct(Product instance); partial void UpdateProduct(Product
instance); partial void DeleteProduct(Product instance); partial
void InsertPurchaseOrderDetail(PurchaseOrderDetail instance); partial
void UpdatePurchaseOrderDetail(PurchaseOrderDetail instance); partial
void DeletePurchaseOrderDetail(PurchaseOrderDetail instance); partial
void InsertProductCategory(ProductCategory instance); partial void
UpdateProductCategory(ProductCategory instance); partial void DeleteProductCategory(ProductCategory
instance); #endregion
----------------------- //Product
tablosuna ait parçalı sınıfa bakarsak -----------------------
//Product tablosuna ilişkin özellikler ve değerleri [Table(Name="Production.Product")]
public partial class Product : INotifyPropertyChanging, INotifyPropertyChanged
{
private static PropertyChangingEventArgs emptyChangingEventArgs
= new PropertyChangingEventArgs(String.Empty);
private
int _ProductID; private string _Name;
private string _ProductNumber; private bool _MakeFlag;
private bool _FinishedGoodsFlag; private string _Color;
private short _SafetyStockLevel; private short _ReorderPoint;
private decimal _StandardCost; private decimal _ListPrice;
private string _Size; private string _SizeUnitMeasureCode;
private string _WeightUnitMeasureCode; private System.Nullable<decimal>
_Weight; private int _DaysToManufacture;
private string _ProductLine; private string _Class;
private string _Style; private System.Nullable<int>
_ProductSubcategoryID; private System.Nullable<int>
_ProductModelID; private System.DateTime _SellStartDate;
private System.Nullable<System.DateTime> _SellEndDate;
private System.Nullable<System.DateTime> _DiscontinuedDate;
private System.Guid _rowguid; private System.DateTime
_ModifiedDate; private EntitySet<PurchaseOrderDetail>
_PurchaseOrderDetails; #region Extensibility Method Definitions
//Listenin bir kısmıdır. Aslında birçok metot bulunmaktadır.
partial void OnLoaded(); partial void OnValidate(System.Data.Linq.ChangeAction
action); partial void OnCreated(); partial void OnProductIDChanging(int
value); partial void OnProductIDChanged(); partial void OnStandardCostChanged();
partial void OnListPriceChanging(decimal value); partial void OnListPriceChanged();
partial void OnSizeChanging(string value); #endregion
public
Product() { this._PurchaseOrderDetails = new EntitySet<PurchaseOrderDetail>(new
Action<PurchaseOrderDetail>(this.attach_PurchaseOrderDetails)
, new Action<PurchaseOrderDetail>(this.detach_PurchaseOrderDetails));
OnCreated(); }
[Column(Storage="_ProductID", AutoSync=AutoSync.OnInsert,
DbType="Int NOT NULL IDENTITY", IsPrimaryKey=true, IsDbGenerated=true)]
public int ProductID { get {
return this._ProductID; } set
{ if ((this._ProductID != value))
{ this.OnProductIDChanging(value);
this.SendPropertyChanging();
this._ProductID = value;
this.SendPropertyChanged("ProductID");
this.OnProductIDChanged(); }
} }
[Column(Storage="_Name", DbType="NVarChar(50) NOT NULL",
CanBeNull=false)] public string Name { get
{ return this._Name;
} set {
if ((this._Name != value)) {
this.OnNameChanging(value);
this.SendPropertyChanging();
this._Name = value;
this.SendPropertyChanged("Name");
this.OnNameChanged(); }
} }
//Özelliklere ilişkin metotlar devam etmektedir...
|
dbml ‘in kod bloğu yukarda ki gibidir. Bu kod bloğunda yalnızca Product
tablosu değil diğer eklemiş olduğumuz tablolarda bulunmaktadır.
Şimdi
yapmamız gereken model içerisine eklemiş olduğumuz tablolara ilişkin verileri
Controller üzerinden çağırarak kullanmaktır. Bu işlemi yapabilmemiz için bir
parçalı sınıf oluşturmalı ve oluşturmuş olduğumuz bu sınıfı ControllerAction
yardımı ile çağırılabilir bir biçime dönüştürmeliyizdir. Ayrıca oluşturmuş olduğumuz
parçalı sınıfın içersinde de yapacağımız işlemleri list içerisinde belirlememiz
gerekmektedir.
Sınıfımızı oluşturmaya başladığımızda uygulamamızda oluşturulmuş
olan isim alanlarına ulaşmak istediğimizde uygulamaismi. dememiz
yeterli olacaktır.
Karşımıza çıkan isim alanları listesinden Models ‘ı seçtikten sonra karşımıza
dört farklı seçebileceğimiz sınıf çıkacaktır. Bunlardan üçü bizim eklediğimiz
tabloları temsil etmektedir. Dördüncüsü ile veri içeriğini temsil etmektedir.
Bu veri içeriği dbml dosyamızda oluşturulmuş olan sınıfın içerisinden bir tiptir.
İçeriğe erişmek için kullanmakta yarar vardır.
Veri içeriğini tanımladıktan
sonra ayrıntılarını görmek istediğimizde, tabloları LinQ içerisinde belirlenmiş
olduğunu görürüz.
Daha sonra yapacağımız işlem ise çağıracak olduğumuz tablonun görülebilmesi
için RenderView üyesinin içerisinde tanımlayarak Controller ‘a istek geldiğinde
anlayabilmesine olanak tanımaktadır. Bu isteği algılayabilmesi de alınan değer
ve değere ilişkin tablo biçimin kod bloğunda yazılması gerekmektedir.
Hazırlıklarımızı tamamladığımıza
göre normal olarak uygulamamızı çalıştırdığımızda sorunsuz bir biçimde derlenmesi
ve işlemesi gerekmektedir.
Uygulamamız sorunsuz bir biçimde derlendi
ve web sayfamız karşımıza geldi. Şimdi ise bizden istek yapmamızı beklemektedir.
Normal zamanlarda form üzeriden sayfaya istek yaptığımızda View ‘ın içerisinde
olan sayfaları çağırmaya çalışacaktır.
Bizde oluşturmuş olduğumuz list
öğesini çağırmak için tarayıcımızın adres çubuğunu http://localhost:49170/Home/List
yazıyoruz. Bu yazdığımız adrese göre tarayıcımız isteğini yapacak ve
Controller da bu istek doğrultusunda gerekli olan sayfayı çağıracaktır.
Fakat her şey düşündüğümüz gibi olmuyor ve aşağıdaki hatayı alıyoruz.
Karşılaştığımız hataya
dikkat ettiyseniz Products.aspx sayfası bulunamadı diyor. Fakat bu Products.aspx
‘i neden arıyor? Biz internet tarayıcımızın adres çubuğuna home/List ‘i çağırmasını
istemiştik. Bunun sebebi Controller içerisinde hazırlamış olduğumuz list member
‘inin içerisinde eğer kullanıcıdan böyle bir istek gelirse adı Product olan
sayfaya yönlendirmesini istemiştik. O da görevini yaparak View/Home klasörünün
altında Products.aspx ‘i aramaktadır. Fakat biz öyle bir sayfa eklemediğimiz
için bulamamaktadır.
O zaman bizde Products.aspx sayfasını ekleyelim
ve sonucun nasıl olacağını görmeye çalışalım. Bu işlemi yapabilmemiz için View/Home
klasörünün üzerinde Add/NewItem diyerek karşımıza ekleyebileceklerimizin listesini
çıkartıyoruz. Bu listeden standart aspx sayfasını seçmek yerine MVC ‘den türetilecek
olan MVCViewPage ‘i seçmek bizim işimizi kolaylaştıracaktır.
Sayfamızı ekledikten sonra
içeriğine rastgele bir şeyler yazarak derlediğimiz zaman adres çubuğunda Home/List
şeklinde bir çağırma olduğu dikkatimizden kaçmamaktadır.
Şimdi ise web
sayfamızın içerisinden modelde tanımlanmış olanların hangilerine ve nasıl erişeceğimize
göz atalım.
Temel asp bilgimizden <% %> bloklarının arasına kod yazılabildiğini
biliyoruz. Şimdi web sayfamızda bu blokları kullanarak verileri göstertmeyi
deneyelim. Bunun için yazmamız kod ViewData ‘dır. Bu kodu kullanmamız sonrasında
intellisense ile karşımıza gelen sınıfların arasında veri içeriğinin de olduğunu
görürüz.
Şimdi
ViewData ‘dan sonra alacağımız özellikleri, sınıfları v.b. diğer bir çok şeyi
Product ‘ın içerisinden almak istiyoruz. Bunu yapmak için, web sayfamızın kod
tarafında hazır olarak oluşturulmuş sınıfa generics (genel) tanımlayarak Product
‘taki bütün verileri almasını sağlayabiliriz. Bunu yapabilmek için aşağıdaki
gibi bir kod oluşturmamız gerekmektedir.
Alınabilecek değerler,
Bu görünebilir veri
değerine Product yazıpta uygulamamızı derledikten sonra web sayfamızın içeriğinden
olan ViewData ‘nın intellisence ile bize getirecekleri aşağıdaki gibi olacaktır.
ViewData ‘nın içerisinde
karşımıza çıkan bu properties ‘lerin içeriklerini görmek istersek yapmamız gereken
işlem kod tarafında tanımlamış olduğumuz Product ‘ı IEnumerable ‘ın içeriğinde
tanımlamak olacaktır.
Bu değişikliğin sonucunda ViewData ile intellisense kullandığımızda karşımıza
extensionlar aşağıdaki gibidir.
Yapacağımız sıradaki işlem
ise Product tablosunun altında yer alan ProductName ‘leri ekrana basmak olacaktır.
Bunu yapabilmek için foreach kullanmamız yeterli olacaktır.
<%@
Page Language="C#" AutoEventWireup="true" CodeBehind="Products.aspx.cs"
Inherits="AdventureWorkMerhaba.Views.Home.Products" %> <%@
Import Namespace="AdventureWorkMerhaba.Models" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" > <head runat="server">
<title></title> </head> <body>
<div> hede... bu
bir deneme sayfasidir
<ul> <%
foreach (Product p in ViewData)
{ %>
<li><%=p.Name%></li>
<% } %>
</ul> </div> </body>
</html> |
Sayfamızı derlediğimiz zaman aldığımız sonuç oldukça iyidir. Bütün liste
karşımızdadır.
Fakat bütün liste karşımızda olmasına rağmen masterpage ‘in tasarımını almamıştır.
Ona erişebilmek için ise index.aspx ‘in içerisinde yer alan MasterPageContainer
‘larını Product.aspx ‘e ekleyerek tasarımı kazanmasını sağlayabiliriz.
Master page ‘imizi ekledikten sonra ise karşılaştığımız listenin daha şirin
ve düzenli gözükebilmesi için css ‘imizin içerisinde yeni bir tasarım oluşturalım.
Oluşturacak olduğumuz tasarım aşağıdaki gibi olacaktır.
Bu hazırladığımız tasarım
sonucunda ise derleme esnasında web sayfamız aşağıdaki gibi bir görünüme kavuşacaktır.
Bu makalemizde MVC
Framework ‘ü ve LinQ to SQL ’i kullanarak verilere erişimi ve sayfada göstermeyi
anlatmaya çalıştık. Bir sonraki makalemizde ise ID ‘ler aldığımız değerleri
kullanarak güncelleme yapmayı ve silmeyi incelemeye çalışacağız.
Umarım
yararlı olmuştur.
Uygulamanın kaynak kodlarına
linkten erişebilirsiniz.
Veri tabanı dosyası kaynak kodlarda değildir. SQL server örnek veritabanından
erişebilmeniz mümkündür. Sizin örneği çalıştırabilmeniz için WebConfig dosyasında
gerekli düzenlemeleri yapmanız gerekmektedir.
Turhal Temizer
http://turhal.blogspot.com
Makale:
Asp.Net MVC Framework - II ASP.NET Turhal Temizer
|
|
|
-
-
Eklenen Son 10
-
Bu Konuda Geçmiş 10
Bu Konuda Yazılmış Yazılmış 10 Makale Yükleniyor
Son Eklenen 10 Makale Yükleniyor
Bu Konuda Yazılmış Geçmiş Makaleler Yükleniyor
|
|