Makale Özeti

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.

Makale

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]

    )ZZ

    WHERE

        SAY BETWEEN ((@PAGE_NO-1)*@PAGE_COUNT)+1 AND @PAGE_NO*@PAGE_COUNT

GO

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

TOTAL SAY MEKANLAR
23 1 anittepe                 
23 2 ayazaga                  
23 3 ayazma                   
23 4 beylikdüzü               
23 5 bostanci                 

[GET_YER] 2,5

TOTAL SAY MEKANLAR
23 6 bostanci                 
23 7 cambridge                
23 8 divrigi                  
23 9 fethiye                  
23 10 gülsuyu                  

[GET_YER] 3,5

TOTAL SAY MEKANLAR
23 11 hindistan                
23 12 istinye                  
23 13 japonya                  
23 14 kadiköy                  
23 15 karsiyaka                

[GET_YER] 4,5

TOTAL SAY MEKANLAR
23 16 kozyatagi                
23 17 kremlin                  
23 18 manchester               
23 19 poligon                  
23 20 resitpasa                

[GET_YER] 5,5

TOTAL SAY MEKANLAR
23 21 salihli5                 
23 22 selimiye                 
23 23 washington               

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

www.mehmetaliecer.com