Asp.NET DataList, PagedDataSource, DataTable ve Cache… Ajax da olursa tadından yenmez.
DataGridView’da ki gibi paging yapmak istiyoruz elimizdeki datalist’e. Dünya kadar hesap kitap işlerinin yanısıra; Microsoft SQL Server da MySQL’de olan LIMIT fonksiyonu yok. Hep yakınırım bundan. MySQL de paging sırasında LIMIT 20,10 dediğimiz zaman 20. satır dan başla 10 adet getir diyebiliyoduk. Bunun Microsoft SQL Server’da ki karşılığı upuzun sql kodları. Row numaralarını alacaksın da onları bi satıra atacaksın da between ile çekeceksin de ölme eşşeğim ölme
PagedDataSource’u kullanabilmek için elimizdeki tüm satırları vermemiz gerekiyor. Bu da sunucuyu cidden yoran bir işlem. Öteki türlü elle vermek gerekiyor herşeyi. Alternatif çözümlerden birisi de; PagedDataSource’a bağladığımız DataTable’ ı cachelemek. Cache derken tüm sayfayı değil. sadece DataTable’ı cachelemek. Akla hemen şu soru geliyor. Kategorilere göre ürün listeleten bir sayfam var. Datatable ı cache lerse hangi kategoriye girsin o süre boyunca aynı kategoriyi gösterir.
Eğer; Cache[KategoriID.ToString()] gibi birşey kullanırsak yada Cache["Kategori" + KategoriID.ToString()] o kategoriID ye göre datatable ımızı cacheleriz. evet bolca ram götüren bir işlem. Fakat özellikle çok tablo, çok sorgu ile çalıştığı zaman gerçekten çok süratli çalışıyor.
Yapacağımız örnekte KonuID’ye göre cache ledim.
KonuID değişkenini viewstate de arıyor. yoksa querystring de bakıyor. oradada yoksa 1 döndürüyor.(debugging sırasındaki üşengeçliğim için 1 döndürüyor
) aynı şey currentpage için de geçerli. currentpage değişkenimiz mevcut sayfa yı tutuyor. ona göre paging yapıyor.
public int CurrentPage
{
get
{
object o = this.ViewState["_CurrentPage"];
if (o == null)
if (Request.QueryString["CurrentPage"] != null)
{
return Convert.ToInt32(Request.QueryString["CurrentPage"])-1;
}
else
return 0;
else
return (int)o;
}
set
{
this.ViewState["_CurrentPage"] = value;
}
}
public int KonuID
{
get
{
object o = this.ViewState["TeknikKonuID"];
if (o == null)
{
if (Request.QueryString["TeknikKonuID"] != null)
{
return Convert.ToInt32(Request.QueryString["TeknikKonuID"]);
}
else
return 1;
}
else
return (int)o;
}
set
{
this.ViewState["TeknikKonuID"] = value;
}
}
Bu arada altrepeater ve ustrepeater adlı iki datalistimiz daha var. Biri üstte öteki altta
Repeater olmasının sebebi runtime da button eklemem. LinkButton değil buton. Sayfa ajax olduğu için; linkbutton sayfayı komple postback yapıyor. Button un stilinden buton izlenimini kaldırabiliyorum.
protected void Listele()
{
PagedDataSource pagedSource = new PagedDataSource();
DataTable dt;
if (Cache[KonuID.ToString()] == null)
{
//cache de yok. oluşturalım...
dt = new DataTable();
}
else
{
//cache de ki mevcut datatable ı kullanalım...
dt = (DataTable)Cache.Get(KonuID.ToString());
}
pagedSource.DataSource = dt.DefaultView;
pagedSource.AllowPaging = true;
pagedSource.PageSize = 10;
pagedSource.CurrentPageIndex = CurrentPage;
altRepeater.Controls.Clear();
ustRepeater.Controls.Clear();
if (dt.Rows.Count <= 10)
{
altRepeater.Visible = false;
ustRepeater.Visible = false;
}
else
{
altRepeater.Visible = true;
ustRepeater.Visible = true;
}
Label lbl = new Label();
lbl.Text = “Sayfa: “;
Label lbl2 = new Label();
lbl2.Text = “Sayfa: “;
ustRepeater.Controls.Add(lbl);
altRepeater.Controls.Add(lbl2);
ToplamSayfa = pagedSource.PageCount;
for (int i = 0; i < pagedSource.PageCount; i++)
{
if (i == CurrentPage)
{
Label lb = new Label();
lb.Text = “” + (i + 1).ToString() + ““;
Label lb2 = new Label();
lb2.Text = “” + (i + 1).ToString() + ““;
ustRepeater.Controls.Add(lb2);
altRepeater.Controls.Add(lb);
}
else
{
Button btn = new Button();
btn.Text = (i + 1).ToString();
btn.CommandName = (i).ToString();
btn.Click+=new EventHandler(lb_Click);
Button btn2 = new Button();
btn2.Text = (i + 1).ToString();
btn2.CommandName = (i).ToString();
btn2.Click += new EventHandler(lb_Click);
btn.BackColor = Color.White;
btn.Style.Add(HtmlTextWriterStyle.TextDecoration, “underline”);
btn.Style.Add(HtmlTextWriterStyle.PaddingLeft,”3px”);
btn.BorderWidth = 0;
btn2.Style.Add(HtmlTextWriterStyle.TextDecoration, “underline”);
btn2.Style.Add(HtmlTextWriterStyle.PaddingLeft, “3px”);
btn2.BorderWidth = 0;
btn2.BackColor = Color.White;
altRepeater.Controls.Add(btn2);
ustRepeater.Controls.Add(btn);
}
}
DataList1.DataSource = pagedSource;
DataList1.DataBind();
}
protected void lb_Click(object sender, EventArgs e)
{
CurrentPage = Convert.ToInt32((sender as Button).CommandName);
Listele();
}
protected void OncekiSayfa_Click(object sender, EventArgs e)
{
CurrentPage–;
Listele();
}
protected void SonrakiSayfa_Click(object sender, EventArgs e)
{
CurrentPage++;
Listele();
}
Ve cache kullanan pagerımız hazır. Unutmamamız gereken; yeni bir ürün eklendiğinde veya listelenen birşey değiştiğinde Cache.Remove(KonuID.ToString()); ile cache den datatable ımızı silmemiz. Bu arada cache de default olarak 15 dakika kalıyor. gayet uygun bir süre.
Umarım uykusuzlukdan dolayı eksik yazmamışımdır.