Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
tarafından Scott Mitchell
Ö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
dinamikORDER BY
ifadeler sağlamak için bir@sortExpressio
deyim kullanın; daha fazla bilgi için T-SQLCASE
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ı GetProductsPagedAndSorted
yeni 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 , @sortExpression
ve @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.
Şekil 1: Saklı Yordamın Üç Giriş Parametresi için Farklı Değerler Deneyin
Ş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 ProductsTableAdapter
sağ 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: GetProductsPagedAndSorted
bu örnekte. Yeni TableAdapter yönteminin mevcut bir saklı yordamı kullanmasını istediğinizi belirterek başlayın.
Ş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.
Ş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.
Ş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.
Ş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 SelectMethod
geçirmeye çalışır. Özellikle, ObjectDataSource adı özelliğin değerine SortParameterName
eşit olan bir giriş parametresi arar. BLL s GetProductsPagedAndSorted
yöntemi adlı sortExpression
sı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:
- GridView, özelliğini üst bilgi bağlantısına tıklanan alanın değeriyle
SortExpression
güncelleştirir - ObjectDataSource, BLL s
GetProductsPagedAndSorted
yöntemini çağırır ve GridView sSortExpression
özelliğini yönteminsortExpression
giriş parametresinin değeri olarak geçirir (uygunstartRowIndex
vemaximumRows
giriş parametresi değerleriyle birlikte) - BLL, DAL s
GetProductsPagedAndSorted
yöntemini çağırır - DAL,
GetProductsPagedAndSorted
saklı yordamını yürütürken,@sortExpression
parametresini (@startRowIndex
ve@maximumRows
giriş parametresi değerleriyle birlikte) geçirir. - 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.
Ş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).
Ş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 SupplierName
ayarlandığı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.
Şekil 9: SupplierName BoundField'ın SortExpression değerini CompanyName olarak değiştirme
Ş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.