Mvc’de Custom Paging, Sorting, Kolon Ekleme ve Excel’e Atma Bölüm2

Selamlar,

Bugün Bölüm1‘de WebGrid ile yaptığımız paging ve custom column konularına devam edeceğiz. Bu makalede dinamik custom sorting ve datayi Excel’e atma konularını inceleyeceğiz.  Öncelikle WebGrid’deki kolonlara tıklanınca sorting nasıl yapılıyor onu inceleyelim.

Aşağıda görüldüğü gibi ‘body‘ altından WebGrid’deki kolonlara yani ‘#grid thead th‘  koşuluna uyan tüm kolon ismlerine erişilir. ‘click‘ durumunda önce Action’a gönderilecek data oluşturulur.

  • sort: O anda sıralama işlemi yapılacak kolon.
  • preSort: Bir önceki sıralama yapılan kolon. Bir önceki kolona göre tekrar sıralama yapılıp yapılmadığna bakılıp, sıralamanın yönü yani ‘sortdir‘ buna göre değiştirilir.
  • sortdir: Sıralama yaapılacak yön. Yani ya yukarıdan aşağı (asc) ya da aşağıdan yukarı (desc). İlk hangi yöne doğru sıralama yapılmış ise mutlaka ters yöne çevrilir. Amaç aynı kolon için üstüste 2 kere sıralama yapılır ise önce ‘asc‘ sonra ‘desc‘ şeklinde çalışması sağlanır.

İlgili data oluşturulduktan sonra ‘EfficientSorting()‘ action’ına gönderilir. Geri dönen Html deger, WebGrid temizlenip yerine html data olarak basılır. Ayrıca önceki makalede bahsedilen footer, manuel olarak oluşturulup yine WebGrid’in sonuna eklenir.

paging.js(Devam):

Aşağıdaki script kodu ile tablonun başındaki sıralama yapılacak kolonların üzerine gelindiğin de mouse’un değişimi ve clicklenebilir olduğunun gösterimi sağlanmıştır.

HomeController.cs (EfficientSorting()): Aşağıda görüldüğü gibi sıralama işlemi sırasında önce database’e bağlanılıp ilgili datalar farklı yollar ile çekilmiştir. Önceki yöntemleride yorumlanarak koyulmuştur ki, size bir fikir verebilsin.

  • presort ve sort ile şu anda ve önceden sıralama yapılan kolonlara bakılmış ve aynı ise ‘desc‘ yani tersten, bir daha sıralama işlemi yapılmıştır.

EfficientSorting’de Çıkarılan Kısımlar( Denenen başka yöntemler): 

  • Yorumlanan ilk yöntemde reflection kullanılmıştır. ‘GetProperty()‘ ile ‘Customer‘ tablosunda string karşılığa denk gelen ilgili kolon çekilmiştir.  En başta ‘dbContext.Customers.OrderBy()‘ methodu içinde ilgili ‘GetProperty()‘ methodunun kullanılmasına linq izin vermemektedir. Nedeni ilgili linq çalıştırılınca, oluşturulacak olan SqlQuery, ilgili methodu yani GetProperty()‘i tanımlayamamaktadır.
  • 2. Yöntem de yukarıdaki maddeden dolayı önce datalar komple çekilmiş ‘data = dbContext.Customers.ToList()‘ daha sonra reflection ile gelen sorgu tipine göre ‘ascending‘ veya ‘descending‘ olarak reflection ile çekilen ‘propertyInfo‘ ile birlikte tüm data üzerinden sıralama yapılmıştır. Tabiki bu da daha sonra performans nedeni ile kaldırılmıştır. Başta ilk 25 kayıt çekilmek istenirken sıralama amaçlı tüm kaydı çekmek doğru değildir:) Bu yapılacak olsa, boşuna manuel sorting yazılmasına gerek yoktur . WebGrid, bunu  bizim için zaten yapıyor :) Ayrıca belli bir koşula göre ‘asc ve desc’ göre kodu dallandırmak kod kalabalığından başka birşey değildir.

Şimdi gelelim gerçek çözüme:

  • Bu işin en hızlı ve pratik çözümü olarak dinamik query, akla en yatkın yöntemlerden biridir.  Tabi bunun farklı birçok çözümü olabilir. Örneğin burada entity framework yerine Dapper‘da kullanılabilirdi. Bu örnekde, ‘dbContext.Customers.SqlQuery()‘ methodu kullanılarak sıralanacak tablo ismi ‘sort’ string olarak eklenip, sorgulama tipi(asc, desc) olan ‘sortdir’da ilgili string query’e eklenip, istenen sayıda kayıt ‘rowPerPage‘ ile çekilir ve data‘ya atanır.
  • İlgili data doldurulduktan sonra ‘WebGrid’ nesnesi serverside da belirlenen parametrelere göre oluşturulup(canPage: false, canSort: false, rowsPerPage: rowPerPage) ‘GetHtml()‘ methodu ile ilgili kolonlar ve sitiller tanımlanıp, dönülecek json nesneye atanır. Burada da ‘Siparisler‘ adlı önceki makalede bahsedilen custom column tanımlanır.
  • Önemli Not: WebGrid oluşturulurken bazı kolonlara allies verilmiştir. Yani gelen kolon ismi, gerçekte tabloda olan kolon ismi artık değildir. Örnek: (grid.Column(“CompanyName”, “Company Name”)). Bu durumda ilgili kolona göre sort işlemi yapıldığında hata alınır. Bunun çözümü ya allies hiç verilmeyecek yada aşağıdaki örnekte olduğu gibi boşluk ” ” karakteri ile bir allies verilip daha sonra tüm boşluklar ve ara boşluklar buradaki gibi temizlenecektir. ‘sort.Trim().Replace(” “, “”)’
  • Son olarak geri dönülecek json nesne, oluşturulan WebGrid Html’i ve toplam sayfalama sayısı ile birlikte geri dönülür.

HomeController.cs/EfficientSorting:

Şimdi sıra geldi ilgili sort işlemine göre paging’i değiştirmeye. Eğer CustomerID’ye göre bir sort işlemi yapılır ise, paging de bu sort yapılan kolona göre dataları sıralamalıdır.

HomeController.cs/EfficientPaging: Aşağıda görüldüğü gibi Paging methodu gösterilecek sayfa olan ‘page‘ parametresi haricinde ‘sort, sortdir‘ şeklinde 2 parametre daha almaktadır. Makalenin başında hatırlayacağınız gibi ‘sort’ sıralama yapılan kolonu ‘sortdir’‘da sıralam yapılacak yönü(asc, desc) belirtmektedir. Öncelikle sıralama işlemi olup olmadığına bakılıp, eger sıralama var ise ‘SqlQuery‘ kullanılıp dinamik queryler yazılır. Böylece parametre olarak gelen sıralanacak kolon ‘sort‘ ile sıralama yönü de ‘sortdir‘  ile ilgili query’e eklenir. Ayrıca sayfalama işlemi için MsSql’deki ‘FETCH, NEXT‘ yapısı kullanılmıştır. Eğer herhangi bir sıralama işlemi yok ise sayfalama için o zaman da linq ile ‘skip, take‘ yapısı kullanılmıştır. Çünkü dinamik query yazmaya gerek yoktur.

  • Ayrıca yorumlanan satırlarda, önce tüm data çekilmiş ve daha sonra çekilen bu tüm data üzerinde sadece ‘CustomID’ye göre sıralama ve sayfalama yapılmıştır.
  • Diğer bir durum, ‘grid.Column(“CustomerID”, “ID”)’ şeklinde WebGrid2’ye verilen allies kaldırılmıştır. Nedeni sorting işleminde ilgili kolon ismine göre uygun bir kolon bulunamamasıdır.
  • Her sayfada toplam 25 kayıt gösterilmektedir..

Yukarıda görüldüğü gibi ilgili data paging ve sorting işlemlerinden sonra çekilmiş ve oluşturulan bir WebGrid’e atanmıştır. Daha sonrada ilgili WebGrid’in, Html’i ve toplam sayfa sayısı geri dönülmüştür.

Şimdir sıra geldi ilgili datayı Excle’e atmaya: Aşağıda görüldüğü gibi controller tarafında sadece ‘View‘ dönülmektedir.

HomeController.cs/GenerateExcel:

Capture

Index.cshtm’deki paging.js: Yukarıda görülen excel resmine tıklandığı zaman ilgili View’a ‘iframe‘ ile gidilmesi ve üzerine gelindiğinde mouse ikonun’un değişimi aşağıdaki function ile sağlanmıştır.

Views/GenerateExcel: Size örnek olması amacı ile ‘WebMatrix.Data‘ kullanılarak view ortamında DB’ye bağlanıp dinamik Query yazılmış ve tüm data ‘db.Query()‘ komutu ile çekilmiştir. Ayrıca ‘data.First().Columns‘ ile gelen kaydın kolon isimleri alınmıştır. İstenir ise ilgili data sunucu tarafından da çekilip model olarak ilgili view’a gönderilebilirdi. Burada önemli nokta ‘Response.AddHeader(“Content-disposition”, “attachment; filename=report.xls”)‘ bilgisi ile sayfanın excel formatında olacağının tanımlanmasıdır. Ayrıca ilgili kolonlar gezilerek kolon isimleri excel’in başına bir tablo içerisinde yazılır. Daha sonra çekilen tüm data gezilerek tablonun içerisine basılır. Index.cshtml’de Excel’e at butonuna tıklanılması ile ilgili ‘GenerateExcel’ view’ına gidilir. Tüm data view ortamında çekilip, kolon isimleri ile bir html table’a basılır ve sayfa hiç açılmadan excel formatında ilgili client’ın makinasına indirilir.

Not: Aşşağıdaki örnekde de görüldüğü gibi Excel’e istenirse, webgrid’deki tüm kolonlar değil de, istenilen kolonlar yine istenilen isimlendirme ile atılabilirler.

Böylece Mvc bir web uygulamasında extra bir tool kullanmadan manuel paging, sorting, bize özel bir column ve excel’e çıktı veren bir örnek yazdık. Böylece hem performansı arttırdık hem de tüm kontrolü ele alarak, istenilen özellikleri rahatlıkla değiştire bildik.

Geldik bir makalenin daha sonuna. Yeni bir makalede görüşmek üzere hoşçakalın.

Source Code: https://github.com/borakasmer/WebGridCustomPageSort

Source:

Herkes Görsün:

Bunlar da hoşunuza gidebilir...

2 Cevaplar

  1. Murad dedi ki:

    Elini<e sağlık hocam yine çok güzel bir makale olmuş.

Bir cevap yazın

E-posta hesabınız yayımlanmayacak.