Aracılığıyla paylaş


Özel Sayfalanmış Verileri Sıralama (VB)

tarafından Scott Mitchell

PDF'i indirin

Önceki öğreticide, bir web sayfasında veri sunarken özel sayfalandırma uygulamayı öğrendik. Bu öğreticide, yukarıdaki örneğin özel sayfalama sıralama desteğini içerecek şekilde nasıl genişletebileceğimizi göreceğiz.

Giriş

Varsayılan sayfalamaya kıyasla, özel sayfalama veriler arasında gezinme performansını katbekat artırabilir ve büyük miktarda veri işlenirken fiili sayfalama uygulama tercihi haline gelir. Özel sayfalama uygulamak, özellikle sıralama eklerken, varsayılan sayfalama uygulamaktan daha karmaşıktır. Bu öğreticide, yukarıdaki örnekten sıralama ve özel sayfalama desteğini içerecek şekilde genişleteceğiz.

Uyarı

Bu öğretici, önceki öğreticiye dayandığı için başlamadan önce, önceki öğreticinin web sayfasında <asp:Content> öğesi içindeki bildirim temelli söz dizimini kopyalayıp EfficientPaging.aspx ve <asp:Content> sayfasındaki SortParameter.aspx öğesi arasına yapıştırmak için bir dakikanızı ayırın. Bir ASP.NET sayfasının işlevselliğini başka bir sayfaya çoğaltma hakkında daha ayrıntılı bir tartışma için , Düzenleme ve Arabirim Ekleme öğreticisine Doğrulama Denetimleri Ekleme öğreticisinin 1. Adımına geri bakın.

1. Adım: Özel Sayfalama Tekniğini Yeniden İnceleme

Özel sayfalamanın düzgün çalışması için, Başlangıç Satırı Dizini ve En Fazla Satır parametrelerine göre belirli bir kayıt alt kümesini verimli bir şekilde alabilen bir teknik uygulamamız gerekir. Bu amaca ulaşmak için kullanılabilecek birkaç teknik vardır. Önceki öğreticide, Microsoft SQL Server 2005'in yeni ROW_NUMBER() derecelendirme işlevini kullanarak bunu gerçekleştirmeyi inceledik. Kısacası derecelendirme işlevi, ROW_NUMBER() belirtilen sıralama düzenine göre derecelenmiş bir sorgu tarafından döndürülen her satıra bir satır numarası atar. Ardından, numaralandırılmış sonuçların belirli bir bölümü döndürülerek uygun kayıt alt kümesi elde edilir. Aşağıdaki sorguda, sıralama sonuçları alfabetik olarak sıralandığında 11 ile 20 arasında numaralandırılmış ürünleri döndürmek için bu tekniğin nasıl kullanılacağı gösterilmektedir ProductName:

SELECT ProductID, ProductName, ...
FROM
   (SELECT ProductID, ProductName, ..., ROW_NUMBER() OVER
    (ORDER BY ProductName) AS RowRank
    FROM Products) AS ProductsWithRowNumbers
WHERE RowRank > 10 AND RowRank <= 20

Bu teknik, belirli bir sıralama düzenini (ProductName bu örnekte alfabetik olarak sıralanmış) kullanarak sayfalama için iyi çalışır, ancak sonuçların farklı bir sıralama ifadesine göre sıralanması için sorgunun değiştirilmesi gerekir. İdeal olarak, yukarıdaki sorgu yan tümcesinde OVER bir parametre kullanmak için yeniden yazılabilir, örneğin:

SELECT ProductID, ProductName, ...
FROM
   (SELECT ProductID, ProductName, ..., ROW_NUMBER() OVER
    (ORDER BY @sortExpression) AS RowRank
    FROM Products) AS ProductsWithRowNumbers
WHERE RowRank > 10 AND RowRank <= 20

Ne yazık ki parametreli ORDER BY yan tümcelere izin verilmiyor. Bunun yerine, bir @sortExpression giriş parametresini kabul eden, ancak aşağıdaki alternatif çözümlerden birini kullanan bir saklı yordam oluşturmamız gerekir.

  • Kullanılabilecek sıralama ifadelerinin her biri için sabit kodlanmış sorgular yazma; ardından, yürütülecek sorguyu belirlemek için T-SQL deyimlerini kullanın IF/ELSE .
  • N giriş parametresine dayalı CASE dinamik ORDER BY ifadeler sağlamak için bir @sortExpressio deyim kullanın; daha fazla bilgi için T-SQL CASE Deyimleri'ndeki Sorgu Sonuçlarını Dinamik Olarak Sıralamak için Kullanılır bölümüne bakın.
  • Saklı yordamda uygun sorguyu dize olarak oluşturun ve ardından dinamik sorguyu sp_executesql yürütmek için sistem saklı yordamını kullanın.

Bu geçici çözümlerin her birinin bazı dezavantajları vardır. İlk seçenek, her olası sıralama ifadesi için bir sorgu oluşturmanızı gerektirdiğinden diğer ikisi kadar korunabilir değildir. Bu nedenle, daha sonra GridView'a yeni, sıralanabilir alanlar eklemeye karar verirseniz, geri dönüp saklı yordamı güncelleştirmeniz de gerekir. İkinci yaklaşım, dize olmayan veritabanı sütunlarına göre sıralama yaparken performans sorunlarına neden olan bazı inceliklere sahiptir ve ayrıca ilki ile aynı bakım sorunlarından muzdariptir. Dinamik SQL kullanan üçüncü seçenek ise, bir saldırganın kendi seçtiği giriş parametresi değerlerini geçirerek saklı yordamı yürütebilmesi durumunda SQL ekleme saldırısı riskini ortaya ekler.

Bu yaklaşımların hiçbiri mükemmel olmasa da, üçüncü seçeneğin üçünün en iyisi olduğunu düşünüyorum. Dinamik SQL kullanımıyla, diğer ikisinin kullanmadığı bir esneklik düzeyi sunar. Ayrıca, SQL ekleme saldırısı yalnızca bir saldırganın kendi seçtiği giriş parametrelerinden geçen saklı yordamı yürütebilmesi durumunda kullanılabilir. DAL parametreli sorgular kullandığından, ADO.NET mimari aracılığıyla veritabanına gönderilen parametreleri korur; bu da SQL ekleme saldırısı güvenlik açığının yalnızca saldırganın saklı yordamı doğrudan yürütebildiği durumda mevcut olduğu anlamına gelir.

Bu işlevi uygulamak için, Northwind veritabanında adlı GetProductsPagedAndSortedyeni bir saklı yordam oluşturun. Bu saklı yordam, üç giriş parametresi kabul etmelidir: @sortExpression, nvarchar(100 türünde bir giriş parametresi olup sonuçların nasıl sıralanacağını belirtir ve ORDER BY cümleciğinde OVER metninin hemen arkasına eklenir; ve @startRowIndex ve @maximumRows, önceki öğreticide incelenen GetProductsPaged saklı yordamının aynı iki tamsayı giriş parametresi. GetProductsPagedAndSorted Aşağıdaki betiği kullanarak saklı yordamı oluşturun:

CREATE PROCEDURE dbo.GetProductsPagedAndSorted
(
    @sortExpression nvarchar(100),
    @startRowIndex int,
    @maximumRows int
)
AS
-- Make sure a @sortExpression is specified
IF LEN(@sortExpression) = 0
    SET @sortExpression = 'ProductID'
-- Issue query
DECLARE @sql nvarchar(4000)
SET @sql = 'SELECT ProductID, ProductName, SupplierID, CategoryID, QuantityPerUnit,
                   UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued,
                   CategoryName, SupplierName
            FROM (SELECT ProductID, ProductName, p.SupplierID, p.CategoryID,
                         QuantityPerUnit, UnitPrice, UnitsInStock, UnitsOnOrder,
                         ReorderLevel, Discontinued,
                  c.CategoryName, s.CompanyName AS SupplierName,
                   ROW_NUMBER() OVER (ORDER BY ' + @sortExpression + ') AS RowRank
            FROM Products AS p
                    INNER JOIN Categories AS c ON
                        c.CategoryID = p.CategoryID
                    INNER JOIN Suppliers AS s ON
                        s.SupplierID = p.SupplierID) AS ProductsWithRowNumbers
            WHERE     RowRank > ' + CONVERT(nvarchar(10), @startRowIndex) +
                ' AND RowRank <= (' + CONVERT(nvarchar(10), @startRowIndex) + ' + '
                + CONVERT(nvarchar(10), @maximumRows) + ')'
-- Execute the SQL query
EXEC sp_executesql @sql

Saklı yordam, @sortExpression parametresi için bir değerin belirtilmiş olduğundan emin olarak başlar. Eksik olduğunda, sonuçlar ProductID ölçütüne göre sıralanır. Ardından dinamik SQL sorgusu oluşturulur. Buradaki dinamik SQL sorgusunun Products tablosundaki tüm satırları almak için kullanılan önceki sorgularımızdan biraz farklı olduğunu unutmayın. Önceki örneklerde, bir alt sorgu kullanarak her ürünün ilişkili kategori s ve sağlayıcı adlarını elde ettik. Bu karar, Veri Erişim Katmanı Oluşturma öğreticisi sırasında alındı ve JOIN'ler kullanılmak yerine alındı çünkü TableAdapter, bu tür sorgular için ilişkili ekleme, güncelleme ve silme yöntemlerini otomatik olarak oluşturamaz. Ancak, sonuçların kategori veya sağlayıcı adlarına göre sıralanması için GetProductsPagedAndSorted saklı yordamı, JOIN kullanmalıdır.

Bu dinamik sorgu, statik sorgu bölümleri ve , @sortExpressionve @startRowIndex@maximumRows parametreleri birleştirilmesiyle oluşturulur. ve @startRowIndex tamsayı parametreleri olduğundan@maximumRows, doğru bir şekilde birleştirilebilmesi için nvarchars'a dönüştürülmeleri gerekir. Bu dinamik SQL sorgusu oluşturulduktan sonra sp_executesql aracılığıyla yürütülür.

Bu saklı yordamı, @sortExpression, @startRowIndex ve @maximumRows parametreleri için farklı değerler kullanarak test edin. Sunucu Gezgini'nden saklı yordam adına sağ tıklayın ve Yürüt'e tıklayın. Bu, giriş parametrelerini girebileceğiniz Saklı Yordamı Çalıştır iletişim kutusunu açar (bkz. Şekil 1). Sonuçları kategori adına göre sıralamak için parametre değeri olarak CategoryName kullanın; sağlayıcının şirket adına göre sıralamak için @sortExpression CompanyName kullanın. Parametre değerlerini sağladıktan sonra Tamam'a tıklayın. Sonuçlar Çıkış penceresinde görüntülenir. Şekil 2'de, UnitPrice azalan düzende sıralanırken 11 ile 20. sırada yer alan ürünler döndürüldüğünde elde edilen sonuçlar gösterilmektedir.

Üç Giriş Parametresi için Saklı Yordamda Farklı Değerler Deneyin

Şekil 1: Saklı Yordamın Üç Giriş Parametresi için Farklı Değerler Deneyin

Hazırlanmış Prosedürün sonuçları Çıkış Penceresinde gözükür

Şekil 2: Saklı Yordam Sonuçları Çıktı Penceresinde Gösterilir (Tam boyutlu görüntüyü görüntülemek için tıklayın)

Uyarı

Belirtilen ORDER BY sütununa göre OVER yan tümcesinde sonuçları sıralarken, SQL Server'ın sonuçları sıralaması gerekir. Sonuçların sıralandığı sütunlarda kümelenmiş bir dizin varsa veya kapsayan bir dizin varsa, ancak aksi takdirde daha maliyetli olabilirse bu hızlı bir işlemdir. Yeterince büyük sorguların performansını artırmak için sonuçların sıralandığı sütun için kümelenmemiş bir dizin eklemeyi göz önünde bulundurun. Daha fazla ayrıntı için SQL Server 2005'te Derecelendirme İşlevleri ve Performansı'na bakın.

2. Adım: Veri Erişimini ve İş Mantığı Katmanlarını Artırma

GetProductsPagedAndSorted Saklı yordam oluşturulduktan sonra, bir sonraki adımımız uygulama mimarimiz aracılığıyla bu saklı yordamı yürütmek için bir yol sağlamaktır. Bu, hem DAL hem de BLL'ye uygun bir yöntem eklemeyi gerektirir. DAL'ye bir yöntem ekleyerek başlayalım. Yazılan Veri Kümesi'ni Northwind.xsd açın, öğesine ProductsTableAdaptersağ tıklayın ve bağlam menüsünden Sorgu Ekle seçeneğini belirleyin. Önceki öğreticide yaptığımız gibi, bu yeni DAL yöntemini mevcut bir saklı yordamı kullanacak şekilde yapılandırmak istiyoruz: GetProductsPagedAndSortedbu örnekte. Yeni TableAdapter yönteminin mevcut bir saklı yordamı kullanmasını istediğinizi belirterek başlayın.

Mevcut Bir Saklı Yordam Kullanmayı Seçin

Şekil 3: Mevcut Saklı Yordamı Kullanmayı Seçin

Kullanılacak saklı yordamı belirtmek için, sonraki ekrandaki açılan listeden GetProductsPagedAndSorted saklı yordamını seçin.

GetProductsPagedAndSorted Saklı Prosedürünü Kullanma

Şekil 4: GetProductsPagedAndSorted Saklı Yordamının Kullanılması

Bu saklı yordam sonuçları olarak bir kayıt kümesi döndürür, böylece sonraki ekranda tablosal veriler döndürdüğünü gösterir.

Depolanan Prosedürün Tablo Verileri Döndürdüğünü Belirtin

Şekil 5: Saklı Yordamın Tablo verilerini döndürdüğünü belirtir

Son olarak, FillPagedAndSorted ve GetProductsPagedAndSorted yöntemlerini sırasıyla adlandırarak, Bir DataTable Doldur ve DataTable Döndür desenlerini kullanan DAL yöntemlerini oluşturun.

Yöntem Adlarını Seçin

Şekil 6: Yöntem Adlarını Seçme

DAL'yi genişletdiğimize göre BLL'ye yönelmeye hazırız. ProductsBLL Sınıf dosyasını açın ve yeni bir yöntem ekleyin: GetProductsPagedAndSorted. Bu yöntem, üç giriş parametresini sortExpression, startRowIndex, ve maximumRows kabul etmesi gerekir ve DAL’ın GetProductsPagedAndSorted yöntemine şöyle bir çağrı yapmalıdır:

<System.ComponentModel.DataObjectMethodAttribute( _
    System.ComponentModel.DataObjectMethodType.Select, False)> _
Public Function GetProductsPagedAndSorted(ByVal sortExpression As String, _
    ByVal startRowIndex As Integer, ByVal maximumRows As Integer) _
    As Northwind.ProductsDataTable
    Return Adapter.GetProductsPagedAndSorted(sortExpression, startRowIndex, maximumRows)
End Function

3. Adım: SortExpression Parametresini Geçirmek için ObjectDataSource'un Yapılandırılması

DAL ve BLL'yi GetProductsPagedAndSorted saklı yordamını kullanan yöntemleri ekleyerek güncelledikten sonra, geriye kalan tek şey, SortParameter.aspx sayfasında ObjectDataSource'u yeni BLL yöntemini kullanacak şekilde yapılandırmak ve kullanıcı tarafından seçilen sütuna göre SortExpression parametresinin iletilmesini sağlamaktır.

ObjectDataSource'un SelectMethod değerini GetProductsPaged'den GetProductsPagedAndSorted'ye değiştirerek başlayın. Bu, Veri Kaynağını Yapılandırma sihirbazı, Özellikler penceresinden veya doğrudan bildirim temelli söz dizimi aracılığıyla yapılabilir. Ardından ObjectDataSource SortParameterName özelliği için bir değer sağlamamız gerekir. Bu özellik ayarlanırsa, ObjectDataSource GridView s SortExpression özelliğini öğesine SelectMethodgeçirmeye çalışır. Özellikle, ObjectDataSource adı özelliğin değerine SortParameterName eşit olan bir giriş parametresi arar. BLL s GetProductsPagedAndSorted yöntemi adlı sortExpressionsıralama ifadesi giriş parametresine sahip olduğundan ObjectDataSource s SortExpression özelliğini sortExpression olarak ayarlayın.

Bu iki değişikliği yaptıktan sonra ObjectDataSource bildirim temelli söz dizimi aşağıdakine benzer olmalıdır:

<asp:ObjectDataSource ID="ObjectDataSource1" runat="server"
    OldValuesParameterFormatString="original_{0}" TypeName="ProductsBLL"
    SelectMethod="GetProductsPagedAndSorted" EnablePaging="True"
    SelectCountMethod="TotalNumberOfProducts" SortParameterName="sortExpression">
</asp:ObjectDataSource>

Uyarı

Önceki öğreticide olduğu gibi, ObjectDataSource'un SelectParameters koleksiyonunda sortExpression, startRowIndex veya maximumRows giriş parametrelerini içermediğinden emin olun.

GridView'da sıralamayı etkinleştirmek için, GridView'un akıllı etiketinde "Sıralamayı Etkinleştir" onay kutusunu işaretleyin. Bu işlem GridView'un AllowSorting özelliğini true olarak ayarlar ve her sütunun üst bilgi metnini LinkButton olarak işler. Son kullanıcı başlık LinkDüğmeleri'nden birine tıkladığında, bir postback işlemi gerçekleşir ve aşağıdaki adımlar meydana gelir:

  1. GridView, özelliğini üst bilgi bağlantısına tıklanan alanın değeriyle SortExpression güncelleştirir
  2. ObjectDataSource, BLL s GetProductsPagedAndSorted yöntemini çağırır ve GridView s SortExpression özelliğini yöntemin sortExpression giriş parametresinin değeri olarak geçirir (uygun startRowIndex ve maximumRows giriş parametresi değerleriyle birlikte)
  3. BLL, DAL s GetProductsPagedAndSorted yöntemini çağırır
  4. DAL, GetProductsPagedAndSorted saklı yordamını yürütürken, @sortExpression parametresini (@startRowIndex ve @maximumRows giriş parametresi değerleriyle birlikte) geçirir.
  5. Saklı yordam, uygun veri alt kümesini BLL'ye döndürür ve bunu ObjectDataSource'a döndürür; Bu veriler daha sonra GridView'a bağlanır, HTML olarak işlenir ve son kullanıcıya gönderilir

Şekil 7'de, UnitPrice'e göre artan düzende sıralandığında sonuçların ilk sayfası gösterilir.

Sonuçlar UnitPrice Ölçütüne Göre Sıralanır

Şekil 7: Sonuçlar UnitPrice'a Göre Sıralanır (Tam boyutlu görüntüyü görüntülemek için tıklayın)

Geçerli uygulama sonuçları ürün adı, kategori adı, birim başına miktar ve birim fiyatına göre doğru şekilde sıralayabilir ancak sonuçları sağlayıcı adına göre sıralamaya çalışmak çalışma zamanı özel durumuyla sonuçlanır (bkz. Şekil 8).

Sonuçları Sağlayıcıya Göre Sıralamaya Çalışmak Aşağıdaki Çalışma Zamanı İstisnasına Neden Oluyor

Şekil 8: Sonuçları Aşağıdaki Çalışma Zamanı Özel Durumundaki Sağlayıcı Sonuçlarına Göre Sıralamaya Çalışma

GridView'un SortExpression BoundField değeri olarak SupplierNameayarlandığından bu özel durum oluşurSupplierName. Ancak, sağlayıcı adı tablosunda aslında Suppliers olarak geçiyor ve biz bu sütun adını CompanyName olarak takma adlandırdık. Ancak OVER işlevi tarafından kullanılan ROW_NUMBER() yan tümcesi diğer adı kullanamaz ve gerçek sütun adını kullanmalıdır. Bu nedenle, BoundField s SupplierName değerini SortExpression SupplierName yerine CompanyName olarak değiştirin (bkz. Şekil 9). Şekil 10'da gösterildiği gibi, bu değişiklik sonrasında sonuçlar sağlayıcıya göre sıralanabilir.

SupplierName BoundField s SortExpression değerini CompanyName olarak değiştirin

Şekil 9: SupplierName BoundField'ın SortExpression değerini CompanyName olarak değiştirme

Sonuçlar artık Sağlayıcıya göre sıralanabilir

Şekil 10: Sonuçlar Artık Sağlayıcıya Göre Sıralanabilir (Tam boyutlu görüntüyü görüntülemek için tıklayın)

Özet

Önceki öğreticide incelediğimiz özel sayfalama uygulaması, tasarım zamanında sonuçların hangi sırayla sıralanacağının belirtilmesini gerektiriyordu. Kısacası bu, uyguladığımız özel disk belleği uygulamasının aynı zamanda sıralama özellikleri sağlayamadığı anlamına geliyordu. Bu öğreticide, ilk saklı yordamı sonuçların sıralanabileceği bir @sortExpression giriş parametresi içerecek şekilde genişleterek bu sınırlamayı aştık.

Bu saklı yordamı ve DAL ile BLL'de yeni yöntemler oluşturduktan sonra, ObjectDataSource'u, GridView'in geçerli SortExpression özelliğini BLL'ye SelectMethod aktaracak şekilde yapılandırarak, hem sıralama hem de özel sayfalama sunan bir GridView uygulamayı başardık.

Mutlu Programlama!

Yazar Hakkında

Yedi ASP/ASP.NET kitabının yazarı ve 4GuysFromRolla.com kurucusu Scott Mitchell, 1998'den beri Microsoft Web teknolojileriyle çalışmaktadır. Scott bağımsız bir danışman, eğitmen ve yazar olarak çalışır. Son kitabı Sams Teach Yourself ASP.NET 24 Hours 2.0'dır. Ona adresinden mitchell@4GuysFromRolla.comulaşabilirsiniz.

Özel Teşekkürler

Bu eğitim serisi, birçok yararlı kişi tarafından incelendi. Bu öğreticinin baş gözden geçireni Carlos Santos oldu. Yaklaşan MSDN makalelerimi gözden geçirmek istiyor musunuz? Öyleyse, mitchell@4GuysFromRolla.com'a bir mesaj bırakın.