![]() | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Grid için Veritabanı Üzerinde Sayfalama(Paging) | 17.01.2008 09:13:00 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Kategori : SQL Server Özet : Herhangi bir veriyi veritabanı üzerinden çekip grid üzerinde göstermek ve grid üzerinde sayfalama yapmak yüksek sayıda satır içeren gridler için yazılımın performans kaybına uğramasına sebep olur. Bu tip bir gösterim veritabanından tüm verilerin çekilip network üzerinden grid üzerine gelir, grid göstereceği veriyi filtreleyerek ekrana getirir. Küçük satır sayısındaki veriler için bu performans kaybı hissedilmesede çok büyük datalarla çalışan programlarda (crm,erp,banka yazılımları) gridin her bind(data bağlama) işleminde (sayfa geçişlerinde, sayfa yüklenmesinde) bu performans kaybı hissedilecektir. Bu tip yapılarda çekilecek veriler için filtreleme işlemleri veritabanı üzerinde yapılırsa ve her bir bind işleminde gösterilmeyecek verinin veritabanı üzerinden alınmaması performans üzerinde çok olumlu etki edecektir. Bu tarz bir mimariyi bu makalede tasarlayacağız. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Grid için Veritabanı Üzerinde Sayfalama(Paging) Herhangi bir veriyi veritabanı üzerinden çekip grid üzerinde göstermek ve grid üzerinde sayfalama yapmak yüksek sayıda satır içeren gridler için yazılımın performans kaybına uğramasına sebep olur. Bu tip bir gösterim veritabanından tüm verilerin çekilip network üzerinden grid üzerine gelir, grid göstereceği veriyi filtreleyerek ekrana getirir. Küçük satır sayısındaki veriler için bu performans kaybı hissedilmesede çok büyük datalarla çalışan programlarda (crm,erp,banka yazılımları) gridin her bind(data bağlama) işleminde (sayfa geçişlerinde, sayfa yüklenmesinde) bu performans kaybı hissedilecektir. Bu tip yapılarda çekilecek veriler için filtreleme işlemleri veritabanı üzerinde yapılırsa ve her bir bind işleminde gösterilmeyecek verinin veritabanı üzerinden alınmaması performans üzerinde çok olumlu etki edecektir. Bu tarz bir mimariyi bu makalede tasarlayacağız. Veritabanı üzerinde dummy veriler için bir tablo oluşturup, daha sonra bu verileri çekebilmek için bir stored procedure oluşturalım. CREATE TABLE [dbo].[yer] ([mekanlar] [nchar] (25) COLLATE SQL_Latin1_General_CP1_CI_AS NULL ,[id] [int] IDENTITY (1, 1) NOT NULL) ON [PRIMARY]END CREATE PROCEDURE [dbo].[GET_YER] ( @PAGE_NO INT,@PAGE_COUNT INT)AS SELECT * FROM ( SELECT COUNT(*) OVER() TOTAL,ROW_NUMBER () OVER(ORDER BY MEKANLAR)AS SAY,MEKANLAR FROM[yer] )ZZWHERE SAY BETWEEN ((@PAGE_NO-1)*@PAGE_COUNT)+1 AND @PAGE_NO*@PAGE_COUNTGO Stored Prosedür iki tane parametre almaktadır. Bunlar @PAGE_NO ve @PAGE_COUNT değerleridir. Bu değerler gridin hangi sayfayı kullanıcılara göstereceği bilgisi(@PAGE_NO ) ve gridini herbir sayfasında toplam kaç tane kayıdın olduğu bilgisidir(PAGE_COUNT ). Bu iki değer sayesinde stored prosedür sayfa üzerinde gösterilecek olan veriyi filtreleme işlemi yapar. Prosedür içerisinde iç içe iki select işlemi vardır. Birinci select işleminde COUNT(*) OVER() TOTAL ile select ile toplam çekilen satır sayısını, ROW_NUMBER() OVER(ORDER BY MEKANLAR)AS SAY ile satır satır sıralı olarak her bir satırın numarasını çekeriz. Dış taraftaki select işlemi ile grid için gerekli olan veri aralığını SAY BETWEEN ((@PAGE_NO-1)*@PAGE_COUNT)+1 AND @PAGE_NO*@PAGE_COUNT kısıtı ile çeker. Prosedürümüzü nasıl çalıştığını daha dikkatli inceleyelim. Burada ilk değer sayfa numarası ikinci değer ise istenilen satır sayısıdır. [GET_YER] 1,5
[GET_YER] 2,5
[GET_YER] 3,5
[GET_YER] 4,5
[GET_YER] 5,5
Görüldüğü gibi grid için gereken sayfayının sadece gösterim yapacağı verinin veritabanından alabilecek bir yapı oluşturulmuştur. Grid üzerinde ise aşağıdaki işlemler yapılarak kullanıcıya çekilen 5 veriyi gösterip gridin toplam satır sayısının 23 olduğu izlemini vermek gerekmedir. Bunun için gridin bir özelliği olan virtualItemCount property'si veritabanından gelen TOTAL sayıya eşitlenecektir. Tasarladığımız bu mimaride seçilen her tablo için gereken sayfa numarası ve sayfa veri satır sayısı değişkenlerini gereken entity katmanına eklememiz gerekmektedir. Yani yer entity miz iki yeni değişken içerecektir. private int _PAGE_NO; private int _PAGE_COUNT; public int PAGE_NO { get { return _PAGE_NO; } set { _PAGE_NO = value; }} public int PAGE_COUNT { get { return _PAGE_COUNT; } set { _PAGE_COUNT = value; }} Data Katmanında prosedürümüzü çağırdığımızda yukarıda tanımladığıımız değişkenleri de parametre olarak stored prosedüre geçirmemiz gerekmektedir. public DataTable GET_YER(entyer parEntyer, DbConnector parDbConnector){ DbParamCollection insDbParamCollection = new DbParamCollection(); insDbParamCollection.Add( "@PAGE_NO", parEntyer.PAGE_NO);insDbParamCollection.Add( "@PAGE_COUNT", parEntyer.PAGE_COUNT); return parDbConnector.ExecuteDataTable("GET_YER", insDbParamCollection);} Aspx sayfasında ise gridimizi uygun şekilde tanımlayıp mimariyi oluşturmamış gerekmektedir. Burada iki önemli nokta vardır bunlardan birincisi gridin AllowCustomPaging özelliğini true yapmak ikincisi ise sayfa geçişlerini yakalayıp veritabanından seçilen sayfanın verisini getirmek için OnPageIndexChanged eventının yakalanmasıdır <asp:DataGrid runat="server" AllowPaging="true" ID="dg" OnPageIndexChanged="dg_PageIndexChanged" AllowCustomPaging="true" > <PagerStyle Mode="NumericPages" /> </asp:DataGrid>Kod tarafında ise öncelikle gridin hangi sayfada olduğu bilgisini global bir değişken ile tutmak gerekmektedir(index değişkeni). Daha sonra entity'mizde olan PAGE_COUNT ve PAGE_NO değişkenlerini uygun şekilde doldurmak gerekmektedir. Her bir sayfa veri çekiminde bu değerler uygun olarak doldurulmalıdır. Koddan da anlaşılacağı gibi gridin sayfalama yapabilmesi için gridin sahip olduğu toplam satır sayısını gridin VirtualItemCount değişkenine atamamız gerekmektedir. Bu değişken stored prosedürümüzden dönen DataTable'ın ilk sütununda yer alan Total alanıdır. İkinci önemli nokta ise grid üzerinde sayfa değişimlerinde gride yeni veri bağlamadan önce hangi sayfaya gidilmek istendiği bilgisini tanımladığımız global değişken vasıtası ile entity'lere ulaştırmaktır. Bunun için gridin PageIndexChanged eventı yakalanıp global değişkenimiz uygun sayfa numarasına getirilir. public int index; protected void Page_Load(object sender, EventArgs e){ if (!Page.IsPostBack){ index = 1; Binddg(); } } public void Binddg(){ busyer insBusYer = new busyer(); entyer insEntYer = new entyer();insEntYer.PAGE_COUNT = 5; insEntYer.PAGE_NO = index; DataTable dt = insBusYer.GET_YER(insEntYer);dg.VirtualItemCount = Convert.ToInt32(dt.Rows[0]["TOTAL"]);dg.PageSize = 5; dg.DataSource = dt; dg.CurrentPageIndex = index-1; dg.DataBind(); } protected void dg_PageIndexChanged(object source, DataGridPageChangedEventArgs e){ dg.CurrentPageIndex = e.NewPageIndex; index = e.NewPageIndex+1; Binddg(); } Gridi oluşturup projemizi çalıştırdığımızda sayfa numaralarının doğru olarak oluştuğunu ve her bir sayfa değişiminde doğru verinin geldiğini görebiliriz. Burada ilk sütunu grid üzerinde göstermek zorunda değilsiniz , giridin ilk sutünunun görünürlüğü ile oynayarak ya da ilk sütün gride atamayarak bu işlemi yapabilirsiniz
Makale ya da kodlarda bulunan hatalar ya da sorularınız için mehmetaliecer@gmail.com adresinden bana ulaşabilirsiniz.İyi çalışmalar. Mehmet Ali ECER
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Yazgelistir.com | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||