Toplu Silme (C#)
tarafından Scott Mitchell
Tek bir işlemde birden çok veritabanı kaydını silmeyi öğrenin. Kullanıcı Arabirimi Katmanı'nda, önceki bir öğreticide oluşturulan gelişmiş bir GridView üzerine inşa ediyoruz. Veri Erişim Katmanı'nda, tüm silme işlemlerinin başarılı olduğundan veya tüm silme işlemlerinin geri alındığından emin olmak için bir işlem içindeki birden çok Silme işlemini sarmalarız.
Giriş
Önceki öğreticide, tam olarak düzenlenebilir bir GridView kullanarak toplu düzenleme arabiriminin nasıl oluşturulacağı keşfedildi. Kullanıcıların sık sık aynı anda birçok kaydı düzenlediği durumlarda, toplu düzenleme arabirimi çok daha az geri gönderme ve klavyeden fareye bağlam anahtarları gerektirir ve böylece son kullanıcının verimliliğini artırır. Bu teknik, kullanıcıların tek seferde birçok kaydı silmesinin yaygın olduğu sayfalar için de benzer şekilde yararlıdır.
Çevrimiçi e-posta istemcisi kullanan herkes en yaygın toplu silme arabirimlerinden birini zaten biliyordur: kılavuzdaki her satırda ilgili Tüm İşaretli Öğeleri Sil düğmesini içeren bir onay kutusu (bkz. Şekil 1). Hem web tabanlı arabirimi hem de tek bir atomik işlem olarak bir dizi kaydı silme yöntemini oluştururken önceki öğreticilerde tüm zor işleri yaptığımız için bu öğretici oldukça kısadır. Onay Kutularının GridView Sütunu Ekleme öğreticisinde, onay kutuları içeren bir sütuna sahip bir GridView oluşturduk ve İşlem öğreticisindeki Veritabanı Değişikliklerini Sarmalama öğreticisinde BLL'de değerlerden ProductID
birini List<T>
silmek için işlem kullanacak bir yöntem oluşturduk. Bu öğreticide, çalışan bir toplu silme örneği oluşturmak için önceki deneyimlerimizi derleyip birleştireceğiz.
Şekil 1: Her Satır bir Onay Kutusu içerir (Tam boyutlu görüntüyü görüntülemek için tıklayın)
1. Adım: Toplu Silme Arabirimini Oluşturma
Onay Kutularının GridView Sütunu Ekleme öğreticisinde toplu silme arabirimini zaten oluşturduğumuz içinBatchDelete.aspx
, sıfırdan oluşturmak yerine doğrudan öğesine kopyalayabiliriz. Başlangıç olarak BatchDelete.aspx
klasördeki sayfayı BatchData
ve klasördeki CheckBoxField.aspx
sayfayı EnhancedGridView
açın. CheckBoxField.aspx
Sayfadan Kaynak görünümüne gidin ve Şekil 2'de gösterildiği gibi etiketler arasındaki işaretlemeyi <asp:Content>
kopyalayın.
Şekil 2: Bildirimli İşaretlemeyi CheckBoxField.aspx
Pano'ya kopyalama (Tam boyutlu resmi görüntülemek için tıklayın)
Ardından, içindeki BatchDelete.aspx
Kaynak görünümüne gidin ve panonun içeriğini etiketlerin içine yapıştırın <asp:Content>
. Ayrıca içindeki code-behind sınıfının CheckBoxField.aspx.cs
içindeki kodu kopyalayıp içindeki BatchDelete.aspx.cs
code-behind sınıfının içine yapıştırın (DeleteSelectedProducts
Button'ın Click
olay işleyicisi, ToggleCheckState
yöntemi ve ve Click
UncheckAll
Düğmeleri için CheckAll
olay işleyicileri). Bu içerik üzerinden kopyalandıktan sonra, BatchDelete.aspx
sayfanın arka planda kod sınıfı aşağıdaki kodu içermelidir:
using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
public partial class BatchData_BatchDelete : System.Web.UI.Page
{
protected void DeleteSelectedProducts_Click(object sender, EventArgs e)
{
bool atLeastOneRowDeleted = false;
// Iterate through the Products.Rows property
foreach (GridViewRow row in Products.Rows)
{
// Access the CheckBox
CheckBox cb = (CheckBox)row.FindControl("ProductSelector");
if (cb != null && cb.Checked)
{
// Delete row! (Well, not really...)
atLeastOneRowDeleted = true;
// First, get the ProductID for the selected row
int productID = Convert.ToInt32(Products.DataKeys[row.RowIndex].Value);
// "Delete" the row
DeleteResults.Text += string.Format
("This would have deleted ProductID {0}<br />", productID);
//... To actually delete the product, use ...
//ProductsBLL productAPI = new ProductsBLL();
//productAPI.DeleteProduct(productID);
//............................................
}
}
// Show the Label if at least one row was deleted...
DeleteResults.Visible = atLeastOneRowDeleted;
}
private void ToggleCheckState(bool checkState)
{
// Iterate through the Products.Rows property
foreach (GridViewRow row in Products.Rows)
{
// Access the CheckBox
CheckBox cb = (CheckBox)row.FindControl("ProductSelector");
if (cb != null)
cb.Checked = checkState;
}
}
protected void CheckAll_Click(object sender, EventArgs e)
{
ToggleCheckState(true);
}
protected void UncheckAll_Click(object sender, EventArgs e)
{
ToggleCheckState(false);
}
}
Bildirim temelli işaretleme ve kaynak kodu kopyaladıktan sonra, tarayıcı üzerinden görüntüleyerek test BatchDelete.aspx
etmek için biraz zaman ayırın. GridView'da ilk on ürünün listelendiği ve her satırın ürün adını, kategorisini ve fiyatını listeleyen bir onay kutusuyla birlikte bir GridView görmeniz gerekir. Üç düğme olmalıdır: Tümünü Denetle, Tümünün İşaretini Kaldır ve Seçili Ürünleri Sil. Tümünü Denetle düğmesine tıklanması tüm onay kutularını seçerken, Tümünün İşaretini Kaldır seçeneği tüm onay kutularını temizler. Seçili Ürünleri Sil'e tıklanması, seçili ürünlerin değerlerini listeleyen ProductID
ancak aslında ürünleri silmeyen bir ileti görüntüler.
Şekil 3: Arabirimin CheckBoxField.aspx
Yeri Taşındı BatchDeleting.aspx
(Tam boyutlu görüntüyü görüntülemek için tıklayın)
2. Adım: İşlemleri Kullanarak İşaretlenmiş Ürünleri Silme
Toplu silme arabirimi üzerine başarıyla kopyalandığında BatchDeleting.aspx
geriye kalan tek şey, kodu, Seçili Ürünleri Sil düğmesinin sınıftaki ProductsBLL
yöntemini kullanarak DeleteProductsWithTransaction
denetlenen ürünleri silecek şekilde güncelleştirmektir. İşlem öğreticisindeki Sarmalama Veritabanı Değişiklikleri'ne eklenen bu yöntem, giriş değeri olarak List<T>
ProductID
kabul eder ve bir işlem kapsamında karşılık gelen ProductID
her birini siler.
DeleteSelectedProducts
Button olay Click
işleyicisi şu anda her GridView satırında yineleme yapmak için aşağıdaki foreach
döngüyu kullanır:
// Iterate through the Products.Rows property
foreach (GridViewRow row in Products.Rows)
{
// Access the CheckBox
CheckBox cb = (CheckBox)row.FindControl("ProductSelector");
if (cb != null && cb.Checked)
{
// Delete row! (Well, not really...)
atLeastOneRowDeleted = true;
// First, get the ProductID for the selected row
int productID = Convert.ToInt32(Products.DataKeys[row.RowIndex].Value);
// "Delete" the row
DeleteResults.Text += string.Format
("This would have deleted ProductID {0}<br />", productID);
//... To actually delete the product, use ...
//ProductsBLL productAPI = new ProductsBLL();
//productAPI.DeleteProduct(productID);
//............................................
}
}
Her satır için CheckBox Web denetimine ProductSelector
program aracılığıyla başvurulur. İşaretlenirse, satırlar ProductID
koleksiyondan DataKeys
alınır ve DeleteResults
Label s Text
özelliği, satırın silinmek üzere seçildiğini belirten bir ileti içerecek şekilde güncelleştirilir.
Sınıfın Delete
yöntemine yapılan çağrı açıklama satırına eklendiğinden ProductsBLL
yukarıdaki kod aslında hiçbir kaydı silmez. Bu silme mantığı uygulanacak olsa, kod ürünleri siler ancak atomik işlem içinde silinmez. Diğer bir ifadeyle, dizideki ilk birkaç silme işlemi başarılı olduysa ancak sonraki bir silme işlemi başarısız olduysa (belki de yabancı anahtar kısıtlama ihlali nedeniyle) bir özel durum oluşturulur ancak bu ürünler silinmiş olarak kalır.
Bölünmezliği sağlamak için bunun yerine sınıfın ProductsBLL
DeleteProductsWithTransaction
yöntemini kullanmamız gerekir. Bu yöntem bir değer listesini kabul ettiğinden ProductID
, önce bu listeyi kılavuzdan derlememiz ve ardından parametre olarak geçirmemiz gerekir. İlk olarak türünde int
bir List<T>
örneği oluştururuz. Döngü içinde foreach
bu öğesine seçili ürün ProductID
değerlerini List<T>
eklememiz gerekir. Döngüden sonra buList<T>
, sınıfın DeleteProductsWithTransaction
yöntemine ProductsBLL
geçirilmelidir. Button olay Click
işleyicisini DeleteSelectedProducts
aşağıdaki kodla güncelleştirin:
protected void DeleteSelectedProducts_Click(object sender, EventArgs e)
{
// Create a List to hold the ProductID values to delete
System.Collections.Generic.List<int> productIDsToDelete =
new System.Collections.Generic.List<int>();
// Iterate through the Products.Rows property
foreach (GridViewRow row in Products.Rows)
{
// Access the CheckBox
CheckBox cb = (CheckBox)row.FindControl("ProductSelector");
if (cb != null && cb.Checked)
{
// Save the ProductID value for deletion
// First, get the ProductID for the selected row
int productID = Convert.ToInt32(Products.DataKeys[row.RowIndex].Value);
// Add it to the List...
productIDsToDelete.Add(productID);
// Add a confirmation message
DeleteResults.Text += string.Format
("ProductID {0} has been deleted<br />", productID);
}
}
// Call the DeleteProductsWithTransaction method and show the Label
// if at least one row was deleted...
if (productIDsToDelete.Count > 0)
{
ProductsBLL productAPI = new ProductsBLL();
productAPI.DeleteProductsWithTransaction(productIDsToDelete);
DeleteResults.Visible = true;
// Rebind the data to the GridView
Products.DataBind();
}
}
Güncelleştirilmiş kod türü List<T>
int
(productIDsToDelete
) oluşturur ve silinecek değerlerle ProductID
doldurur. Döngüden foreach
sonra, seçilen en az bir ürün varsa, sınıfın ProductsBLL
DeleteProductsWithTransaction
yöntemi çağrılır ve bu liste geçirilir. DeleteResults
Etiket de görüntülenir ve veriler GridView'a yönlendirilir (böylece yeni silinen kayıtlar artık kılavuzda satır olarak görünmez).
Şekil 4'de, silmek üzere bir dizi satır seçildikten sonra GridView gösterilmektedir. Şekil 5'de, Seçili Ürünleri Sil düğmesine tıkladıktan hemen sonra ekran gösterilir. Şekil 5'te ProductID
silinen kayıtların değerlerinin GridView'un altındaki Etiket'te görüntülendiğini ve bu satırların artık GridView'da olmadığını unutmayın.
Şekil 4: Seçili Ürünler Silinecek (Tam boyutlu görüntüyü görüntülemek için tıklayın)
Şekil 5: Silinen Ürün ProductID
Değerleri GridView Altında Listelenmiştir (Tam boyutlu görüntüyü görüntülemek için tıklayın)
Not
Yöntemin DeleteProductsWithTransaction
bölünmezliğini test etmek için tabloya Order Details
bir ürün için el ile giriş ekleyin ve ardından bu ürünü silmeyi deneyin (diğerleriyle birlikte). ürünü ilişkili bir siparişle silmeye çalışırken yabancı anahtar kısıtlaması ihlali alırsınız, ancak diğer seçili ürün silmelerinin nasıl geri alınacağını not edin.
Özet
Toplu silme arabirimi oluşturmak için, onay kutuları içeren bir sütun içeren bir GridView ve tıklandığında seçili satırların tümünü tek bir atomik işlem olarak silecek bir Düğme Web denetimi eklenmesi gerekir. Bu öğreticide, önceki iki öğreticide yapılan işleri birlikte birleştirerek, Onay Kutularının GridView Sütunu Ekleme ve İşlem içindeki Veritabanı Değişikliklerini Sarmalama gibi bir arabirim oluşturmştuz. İlk öğreticide onay kutuları içeren bir GridView sütunu oluşturduk ve ikincisinde BLL'de bir değer geçirildiğinde bunların tümünü bir işlem kapsamında silen bir List<T>
ProductID
yöntem uyguladık.
Sonraki öğreticide toplu eklemeler gerçekleştirmek için bir arabirim oluşturacağız.
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ışmaktadır. Son kitabı Sams Teach Yourself ASP.NET 24 Saat içinde 2.0. Adresine adresinden veya adresinden ulaşabileceğiniz http://ScottOnWriting.NETblogu aracılığıyla ulaşabilirsinizmitchell@4GuysFromRolla.com.
Özel Teşekkürler
Bu öğretici serisi birçok yararlı gözden geçiren tarafından gözden geçirildi. Bu öğreticinin baş gözden geçirenleri Hilton Giesenow ve Teresa Murphy'ydi. Yaklaşan MSDN makalelerimi gözden geçirmek istiyor musunuz? Öyleyse, bana bir satır mitchell@4GuysFromRolla.combırakın.