Veritabanı Değişikliklerini Bir İşlemin İçinde Sarmalama (VB)

Scott Mitchell tarafından

Kodu indirin veya PDF 'yi indirin

Bu öğretici, veri toplu işlerini güncelleştirme, silme ve ekleme konusunda görünen dört ilkidir. Bu öğreticide, veritabanı işlemlerinin toplu iş değişikliklerinin bir atomik işlem olarak nasıl gerçekleştirilebildiğini öğrenir, bu da tüm adımların başarılı veya tüm adımların başarısız olmasını sağlar.

Giriş

Veri öğreticisini ekleme, güncelleştirme ve silmeye Ilişkin genel bakışa Başlarken, GridView, satır düzeyinde Düzenle ve silme için yerleşik destek sağlar. Fareyle birkaç tıklamayla, bir kod satırı yazmadan zengin veri değişikliği arabirimi oluşturmak mümkündür. bu nedenle, her satır için Düzenle ve siliniyor içeriklerde olduğu sürece. Ancak, bazı senaryolarda bu yeterli değildir ve kullanıcılara bir kayıt kümesini düzenleme veya silme olanağı sağlamamız gerekir.

Örneğin, çoğu Web tabanlı e-posta istemcisi, her satırın e-posta bilgilerini (konu, gönderen ve benzeri) içeren bir onay kutusu içerdiği her iletiyi listelemek için bir kılavuz kullanır. Bu arabirim, kullanıcının birden çok iletiyi denetleyerek ve sonra seçili Iletileri Sil düğmesine tıklayarak silmesine izin verir. Toplu düzenleme arabirimi, kullanıcıların birçok farklı kaydı yaygın olarak düzenleyebildiği durumlarda idealdir. Kullanıcının Düzenle ' ye tıklaması, değişiklik yapması ve ardından değiştirilmesi gereken her kayıt için Güncelleştir ' e tıklaması yerine, bir Batch düzenleme arabirimi her bir satırı düzenleme arabirimiyle işler. Kullanıcı değiştirilmesi gereken satır kümesini hızlıca değiştirebilir ve sonra Tümünü Güncelleştir düğmesine tıklayarak bu değişiklikleri kaydeder. Bu öğretici kümesinde, verilerin toplu olarak eklenmesi, düzenlenmesine ve silinmesine yönelik arabirimlerin nasıl oluşturulacağını inceleyeceğiz.

Toplu işlem gerçekleştirirken, toplu işteki bazı işlemlerden bazılarının başarılı olması durumunda başarısız olması gerekip gerekmediğini belirleme açısından önemlidir. Toplu işi silme arabirimi-seçili olan ilk kayıt başarıyla silinirse ne olması gerekir, ancak ikinci biri başarısız olursa, yabancı anahtar kısıtlaması ihlali nedeniyle ne olur? İlk kaydın silinmesi geri alınır mi yoksa ilk kaydın silinme için kabul edilebilir mi?

Toplu işlemin bir atomik işlemolarak değerlendirilmesini istiyorsanız, tüm adımların başarılı veya adımların tümü başarısız olursa, veri erişim katmanının veritabanı işlemlerineyönelik destek içerecek şekilde artırılması gerekir. Veritabanı işlemleri, işlemin şemsiye altında yürütülen INSERT, UPDATEve DELETE deyimlerinin kararlılığını garanti eder ve tüm modern veritabanı sistemleri tarafından desteklenen bir özelliktir.

Bu öğreticide, veritabanı işlemlerini kullanmak için DAL genişletme bölümüne bakacağız. Sonraki öğreticiler, toplu iş ekleme, güncelleştirme ve silme arabirimleri için Web sayfalarını uygulamayı inceler. Haydi başlayın!

Note

Toplu işlemdeki verileri değiştirirken, kararlılık her zaman gerekli değildir. Bazı senaryolarda, bir Web tabanlı e-posta istemcisinden bir e-posta kümesini silerken, bazı veri değişikliklerinin başarılı olması ve aynı toplu işteki diğer kişilerin başarısız olması kabul edilebilir. Silme işlemi boyunca bir veritabanı hatası algıladığında, bu, hata olmadan işlenen kayıtların silinmesini de kabul eder. Bu gibi durumlarda, DAL veritabanı işlemlerini destekleyecek şekilde değiştirilmemelidir. Ancak, kararlılık 'in çok önemli olduğu diğer toplu işlem senaryoları vardır. Bir müşteri fonlarını bir banka hesabından diğerine taşıdıkça iki işlem gerçekleştirilmelidir: fonlar ilk hesaptan düşülmeli ve sonra ikincisine eklenmelidir. Bankanın ilk adımı başarılı bir şekilde gerçekleştiremeyebilir, ancak ikinci adım başarısız olsa da, müşterileri daha iyi bir şekilde daha fazla olmaz. Bu öğreticide ilerleyerek ve veritabanı işlemlerini desteklemek için DAL geliştirmeleri uygulayıp, bunları Batch ekleme, güncelleştirme ve silme toplu işlemlerinde kullanmayı planlamıyorsanız, aşağıdaki üç öğreticide oluşturacağız.

Işlemlere genel bakış

Çoğu veritabanı, birden çok veritabanı komutunun tek bir mantıksal iş biriminde gruplandırılmasına olanak sağlayan işlemleriçin destek içerir. Bir işlemi oluşturan veritabanı komutlarının atomik olduğu garanti edilir, yani tüm komutların başarısız olduğu veya tümünün başarılı olacağı anlamına gelir.

Genel olarak, işlemler SQL deyimleriyle aşağıdaki model kullanılarak uygulanır:

  1. İşlemin başlangıcını belirtir.
  2. İşlemi oluşturan SQL deyimlerini yürütün.
  3. 2. adımdaki deyimlerden birinde bir hata varsa, işlemi geri alın.
  4. 2. adımdaki tüm deyimler hata olmadan tamamlandıysanız, işlemi yürütün.

İşlemin oluşturulması, yürütülmesi ve geri dönmesi için kullanılan SQL deyimleri, SQL betikleri yazarken veya saklı yordamlar oluştururken el ile veya ADO.NET ya da System.Transactions ad alanındakisınıfların kullanılmasıyla programlama yoluyla el ile girilebilir. Bu öğreticide, yalnızca ADO.NET kullanarak işlem yönetimini inceleyeceğiz. Gelecekteki bir öğreticide, veri erişim katmanında saklı yordamların nasıl kullanılacağına göz atacağız. Bu durumda, işlemleri oluşturmak, geri almak ve yürütmek için SQL deyimlerini keşfedeceğiz. Bu sırada daha fazla bilgi için SQL Server saklı yordamlarındaki Işlemleri yönetme konusuna bakın.

Note

System.Transactions ad alanındaki TransactionScope sınıfı , geliştiricilerin bir işlem kapsamındaki bir deyim serisini programlama yoluyla sarmasını ve bir Microsoft SQL Server veritabanı, Oracle veritabanı ve bir Web hizmeti gibi iki farklı veritabanı ya da heterojen veri deposu türleri gibi birden çok kaynağı içeren karmaşık işlemler için destek içerir. ADO.NET sınıfı TransactionScope yerine bu öğreticide ADO.NET işlemleri kullanmaya karar verdim ve çoğu durumda, çok daha az kaynak kullanımı. Ayrıca, bazı senaryolarda TransactionScope sınıfı Microsoft Dağıtılmış İşlem Düzenleyicisi (MSDTC) kullanır. MSDTC 'nin içindeki yapılandırma, uygulama ve performans sorunları, Bu öğreticilerin kapsamını özelleştirilmiş ve gelişmiş bir konuyla ve bunların ötesinde kolaylaştırır.

ADO.NET ' de SqlClient sağlayıcısıyla çalışırken işlemler, bir SqlTransaction nesnesidöndüren SqlConnection sınıf s BeginTransaction yöntemineyapılan bir çağrıyla başlatılır. İşlemi oluşturan veri değiştirme deyimleri try...catch bir blok içine yerleştirilir. try bloğundaki bir ifadede bir hata oluşursa, yürütme, işlemin SqlTransaction nesne s Rollback yöntemiaracılığıyla geri aktargetirilebileceği catch bloğuna aktarılır. Tüm deyimler başarıyla tamamlandıysanız, try bloğunun sonundaki SqlTransaction nesne s Commit yöntemine yapılan bir çağrı işlemi kaydeder. Aşağıdaki kod parçacığında bu desenler gösterilmektedir. Ek sözdizimi ve ADO.NET ile işlem kullanma örnekleri için işlem Ile veritabanı tutarlılığını koruma konusuna bakın.

' Create the SqlTransaction object
Dim myTransaction As SqlTransaction = SqlConnectionObject.BeginTransaction();
Try
    '
    ' ... Perform the database transaction�s data modification statements...
    '
    ' If we reach here, no errors, so commit the transaction
    myTransaction.Commit()
Catch
    ' If we reach here, there was an error, so rollback the transaction
    myTransaction.Rollback()
    Throw
End Try

Varsayılan olarak, bir türü belirtilmiş veri kümesindeki TableAdapters işlemleri kullanmaz. Bir işlemin kapsamı içinde bir dizi veri değişikliği deyimi gerçekleştirmek için yukarıdaki kalıbı kullanan ek yöntemler dahil olmak üzere TableAdapter sınıflarını geliştirmemiz gereken işlemler için destek sağlamak üzere. 2. adımda, bu yöntemleri eklemek için kısmi sınıfların nasıl kullanılacağını öğreneceğiz.

1. Adım: toplu veri Web sayfalarıyla çalışmayı oluşturma

Veritabanı işlemlerini desteklemek için DAL 'nin nasıl geliştirdiğine yönelik keşfetmeye başlamadan önce, bu öğretici için ihtiyaç duyduğumuz ASP.NET Web sayfalarını ve bu öğreticiyi izleyen üç işlem için ilk olarak bir süre sürme. BatchData adlı yeni bir klasör ekleyerek başlayın ve ardından her sayfayı Site.master ana sayfayla ilişkilendirerek aşağıdaki ASP.NET sayfalarını ekleyin.

  • Default.aspx
  • Transactions.aspx
  • BatchUpdate.aspx
  • BatchDelete.aspx
  • BatchInsert.aspx

SqlDataSource ile Ilgili öğreticiler için ASP.NET sayfaları ekleyin

Şekil 1: SqlDataSource Ile ilgili öğreticiler Için ASP.NET sayfaları ekleme

Diğer klasörlerde olduğu gibi, Default.aspx kendi bölümünde öğreticileri listelemek için SectionLevelTutorialListing.ascx Kullanıcı denetimini kullanacaktır. Bu nedenle, bu kullanıcı denetimini Çözüm Gezgini sayfa s Tasarım görünümü üzerine sürükleyerek Default.aspx ekleyin.

SectionLevelTutorialListing. ascx Kullanıcı denetimini default. aspx öğesine eklemek

Şekil 2: SectionLevelTutorialListing.ascx kullanıcı denetimini Default.aspx ekleyin (tam boyutlu görüntüyü görüntülemek için tıklayın)

Son olarak, bu dört sayfayı Web.sitemap dosyasına girdi olarak ekleyin. Özellikle, site haritasını özelleştirdikten sonra aşağıdaki biçimlendirmeyi ekleyin <siteMapNode>:

<siteMapNode title="Working with Batched Data" 
    url="~/BatchData/Default.aspx" 
    description="Learn how to perform batch operations as opposed to 
                 per-row operations.">
    
    <siteMapNode title="Adding Support for Transactions" 
        url="~/BatchData/Transactions.aspx" 
        description="See how to extend the Data Access Layer to support 
                     database transactions." />
    <siteMapNode title="Batch Updating" 
        url="~/BatchData/BatchUpdate.aspx" 
        description="Build a batch updating interface, where each row in a 
                      GridView is editable." />
    <siteMapNode title="Batch Deleting" 
        url="~/BatchData/BatchDelete.aspx" 
        description="Explore how to create an interface for batch deleting 
                     by adding a CheckBox to each GridView row." />
    <siteMapNode title="Batch Inserting" 
        url="~/BatchData/BatchInsert.aspx" 
        description="Examine the steps needed to create a batch inserting 
                     interface, where multiple records can be created at the 
                     click of a button." />
</siteMapNode>

Web.sitemapgüncelleştirildikten sonra Öğreticiler Web sitesini bir tarayıcıdan görüntülemek için bir dakikanızı ayırın. Sol taraftaki menüde artık toplu veri öğreticileri ile çalışma için öğeler yer almaktadır.

Site Haritası artık toplu veri öğreticileri ile çalışmaya yönelik girişleri Içerir

Şekil 3: site haritasında artık toplu veri öğreticileri ile çalışmaya yönelik girişler yer almaktadır

2. Adım: veri erişim katmanını, veritabanı Işlemlerini destekleyecek şekilde güncelleştirme

İlk öğreticide geri değindiğimiz gibi, bir veri erişim katmanı oluştururken, Içindeki türü belirtilmiş veri kümesi DataTable ve TableAdapters ' den oluşur. TableAdapters, veritabanından verileri veri okuma, DataTable üzerinde yapılan değişikliklerle veritabanını güncelleştirme, vb. gibi verileri bir veritabanına dönüştürür. TableAdapters 'in, Batch Update ve DB-Direct olarak adlandırılan verileri güncelleştirmek için iki desen sunmaya yönelik olduğunu hatırlayın. Batch Update düzeniyle, TableAdapter bir DataSet, DataTable veya DataRow koleksiyonu iletilir. Bu veriler, her Inserted, Modified veya Deleted satırı için numaralandırılır, InsertCommand, UpdateCommandveya DeleteCommand yürütülür. DB-Direct düzeniyle, TableAdapter, tek bir kaydı eklemek, güncelleştirmek veya silmek için gereken sütunların değerlerini geçti. Daha sonra DB doğrudan model yöntemi, uygun InsertCommand, UpdateCommandveya DeleteCommand ifadesini yürütmek için bu geçirilen değerleri kullanır.

Kullanılan güncelleştirme düzeniyle bağımsız olarak, TableAdapters otomatik oluşturulan Yöntemler işlemleri kullanmaz. Varsayılan olarak, TableAdapter tarafından gerçekleştirilen her bir INSERT, Update veya delete tek bir ayrık işlem olarak değerlendirilir. Örneğin, veritabanına on kayıt eklemek için BLL içindeki bazı kodlar tarafından DB-Direct deseninin kullanıldığını düşünün. Bu kod, TableAdapter s Insert yöntemini on kez çağırırdı. İlk beş ekleme başarılı, ancak altıncı bir özel durumla sonuçlanmış ise, ilk beş kayıt veritabanında kalır. Benzer şekilde, bir DataTable içindeki eklenen, değiştirilen ve silinen satırlarda ekleme, güncelleştirme ve silme işlemleri gerçekleştirmek için toplu güncelleştirme düzeninde kullanılırsa, ilk birkaç değişiklik başarılı olduysa ancak daha sonra bir hatayla karşılaştıysa, bu, önceki değişiklikleri tamamlandı, veritabanında kalır.

Belirli senaryolarda, bir dizi değişiklik genelinde kararlılık sağlamak istiyoruz. Bunu gerçekleştirmek için, bir işlemin şemsiye altında InsertCommand, UpdateCommandve DeleteCommand çalıştıran yeni yöntemler ekleyerek TableAdapter 'ı el ile genişletmelidir. Veri erişim katmanı oluşturma bölümünde, yazılan veri kümesi içindeki DataTable işlevlerinin işlevselliğini uzatmak için kısmi sınıflar kullanma konusunda baktık. Bu teknik, TableAdapters ile de kullanılabilir.

Yazılan veri kümesi Northwind.xsd App_Code klasör s DAL alt klasöründe bulunur. TransactionSupport adlı DAL klasörde bir alt klasör oluşturun ve ProductsTableAdapter.TransactionSupport.vb adlı yeni bir sınıf dosyası ekleyin (bkz. Şekil 4). Bu dosya, bir işlem kullanarak veri değişiklikleri gerçekleştirmeye yönelik yöntemleri içeren ProductsTableAdapter kısmi uygulamasını tutacaktır.

TransactionSupport adlı bir klasör ve ProductsTableAdapter. TransactionSupport. vb adlı bir sınıf dosyası ekleyin

Şekil 4: TransactionSupport adlı bir klasör ve ProductsTableAdapter.TransactionSupport.vb adlı bir sınıf dosyası ekleyin

ProductsTableAdapter.TransactionSupport.vb dosyasına aşağıdaki kodu girin:

Imports System.Data
Imports System.Data.SqlClient
Namespace NorthwindTableAdapters
    Partial Public Class ProductsTableAdapter
        Private _transaction As SqlTransaction
        Private Property Transaction() As SqlTransaction
            Get
                Return Me._transaction
            End Get
            Set(ByVal Value As SqlTransaction)
                Me._transaction = Value
            End Set
        End Property
        Public Sub BeginTransaction()
            ' Open the connection, if needed
            If Me.Connection.State <> ConnectionState.Open Then
                Me.Connection.Open()
            End If
            ' Create the transaction and assign it to the Transaction property
            Me.Transaction = Me.Connection.BeginTransaction()
            ' Attach the transaction to the Adapters
            For Each command As SqlCommand In Me.CommandCollection
                command.Transaction = Me.Transaction
            Next
            Me.Adapter.InsertCommand.Transaction = Me.Transaction
            Me.Adapter.UpdateCommand.Transaction = Me.Transaction
            Me.Adapter.DeleteCommand.Transaction = Me.Transaction
        End Sub
        Public Sub CommitTransaction()
            ' Commit the transaction
            Me.Transaction.Commit()
            ' Close the connection
            Me.Connection.Close()
        End Sub
        Public Sub RollbackTransaction()
            ' Rollback the transaction
            Me.Transaction.Rollback()
            ' Close the connection
            Me.Connection.Close()
        End Sub
    End Class
End Namespace

Burada sınıf bildiriminde Partial anahtar sözcüğü, içinde eklenen üyelerin NorthwindTableAdapters ad alanındaki ProductsTableAdapter sınıfına ekleneceğini belirtir. Dosyanın en üstündeki Imports System.Data.SqlClient bildirimine göz önünde edin. TableAdapter, SqlClient sağlayıcısını kullanacak şekilde yapılandırıldığından, kendi komutlarını veritabanına vermek için bir SqlDataAdapter nesnesi kullanır. Sonuç olarak, işlemi başlatmak ve sonra yürütmek ya da geri almak için SqlTransaction sınıfını kullandık. Microsoft SQL Server dışında bir veri deposu kullanıyorsanız, uygun sağlayıcıyı kullanmanız gerekir.

Bu yöntemler, bir işlemi başlatmak, geri almak ve yürütmek için gereken yapı taşlarını sağlar. Bunlar Publicişaretlenir, bu, DAL içindeki başka bir sınıftan veya BLL gibi mimarideki başka bir katmandan ProductsTableAdapterkullanılmasını sağlar. BeginTransaction TableAdapter iç SqlConnection açar (gerekirse), işlemi başlatır ve Transaction özelliğine atar ve işlemi iç SqlDataAdapter s SqlCommand nesnelerine ekler. CommitTransaction ve RollbackTransactionRollback nesnesini kapatmadan önce, sırasıyla Transaction nesne s Commit ve Connection Yöntemleri çağırın.

3. Adım: bir Işlemin şemsiye altında verileri güncelleştirmek ve silmek için yöntemler ekleme

Bu yöntemler tamamlansa, bir işlemin şemsiye altında bir dizi komut gerçekleştiren ProductsDataTable veya BLL 'e Yöntemler eklemeye hazırız. Aşağıdaki yöntem bir işlem kullanarak bir ProductsDataTable örneğini güncelleştirmek için Batch güncelleştirme modelini kullanır. BeginTransaction yöntemini çağırarak bir işlem başlatır ve sonra veri değiştirme deyimlerini vermek için bir Try...Catch bloğu kullanır. Adapter nesne Update yöntemine yapılan çağrı bir özel durumla sonuçlanırsa, yürütme hareketin geri alındığı ve özel durumun yeniden oluşturulduğu catch bloğuna aktarılır. Update yönteminin, sağlanan ProductsDataTable satırları numaralandırarak ve gerekli InsertCommand, UpdateCommandve DeleteCommand işlemlerini gerçekleştirerek Batch güncelleştirme modelini uyguladığını unutmayın. Bu komutlardan herhangi biri bir hata ile sonuçlanırsa işlem, işlem ömrü boyunca yapılan önceki değişiklikleri geri alarak geri alınır. Update deyimin hatasız tamamlanabilmesi gerekir, işlem tamamen işlenir.

Public Function UpdateWithTransaction _
    (ByVal dataTable As Northwind.ProductsDataTable) As Integer
    
    Me.BeginTransaction()
    Try
        ' Perform the update on the DataTable
        Dim returnValue As Integer = Me.Adapter.Update(dataTable)
        ' If we reach here, no errors, so commit the transaction
        Me.CommitTransaction()
        Return returnValue
    Catch
        ' If we reach here, there was an error, so rollback the transaction
        Me.RollbackTransaction()
        Throw
    End Try
End Function

UpdateWithTransaction yöntemini ProductsTableAdapter.TransactionSupport.vbparçalı sınıfı aracılığıyla ProductsTableAdapter sınıfına ekleyin. Alternatif olarak, bu yöntem bazı küçük sözdizimsel değişikliklerle Iş mantığı katmanı s ProductsBLL sınıfına eklenebilir. Yani, Me.BeginTransaction(), Me.CommitTransaction()ve Me.RollbackTransaction() anahtar sözcüğünün Me Adapter ile değiştirilmeleri gerekir (Bu Adapter, ProductsBLL türündeki ProductsTableAdapterbir özelliğin adıdır).

UpdateWithTransaction yöntemi Batch güncelleştirme modelini kullanır, ancak aşağıdaki yöntemin gösterdiği gibi bir dizi VERITABANı doğrudan çağrısı da bir işlemin kapsamı içinde kullanılabilir. DeleteProductsWithTransaction yöntemi, silinecek ProductID s olan Integertüründe bir List(Of T) girdi olarak kabul eder. Yöntemi, BeginTransaction çağrısı yoluyla işlemi başlatır ve sonra Try bloğunda, her ProductID değeri için DB-Direct model Delete yöntemini çağıran sağlanan liste boyunca yinelenir. Delete çağrılarından herhangi biri başarısız olursa, denetim işlemin geri alındığı ve özel durumun yeniden oluşturulduğu Catch bloğuna aktarılır. Delete yapılan tüm çağrılar başarılı olursa işlem gerçekleştirilir. Bu yöntemi ProductsBLL sınıfına ekleyin.

Public Sub DeleteProductsWithTransaction _
    (ByVal productIDs As System.Collections.Generic.List(Of Integer))
    
    ' Start the transaction
    Adapter.BeginTransaction()
    Try
        ' Delete each product specified in the list
        For Each productID As Integer In productIDs
            Adapter.Delete(productID)
        Next
        ' Commit the transaction
        Adapter.CommitTransaction()
    Catch
        ' There was an error - rollback the transaction
        Adapter.RollbackTransaction()
        Throw
    End Try
End Sub

Birden çok TableAdapters arasında Işlem uygulama

Bu öğreticide incelenen işlemle ilgili kod, ProductsTableAdapter birden çok deyimin atomik bir işlem olarak işlenmesine izin verir. Ancak, farklı veritabanı tablolarında birden fazla değişiklik otomatik olarak gerçekleştirilmesi gerekiyorsa ne olur? Örneğin, bir kategoriyi silerken, önce geçerli ürünlerini başka bir kategoriye yeniden atamak isteyebilirsiniz. Bu iki adım, ürünleri yeniden atayarak ve kategoriyi silmenin atomik bir işlem olarak yürütülmesi gerekir. Ancak ProductsTableAdapter yalnızca Products tablosunu değiştirme yöntemleri içerir ve CategoriesTableAdapter yalnızca Categories tablosunu değiştirme yöntemlerini içerir. Bu nedenle bir işlem hem TableAdapters?

Bir seçenek, DeleteCategoryAndReassignProducts(categoryIDtoDelete, reassignToCategoryID) adlı CategoriesTableAdapter bir yöntem eklemektir ve bu yöntemin, her ikisi de ürünleri yeniden atar ve saklı yordamda tanımlanan bir işlemin kapsamındaki kategoriyi sildiği bir saklı yordam çağırmasıdır. Daha sonraki bir öğreticide saklı yordamlarda işlem başlatma, işleme ve geri alma işlemlerine bakacağız.

Başka bir seçenek de DeleteCategoryAndReassignProducts(categoryIDtoDelete, reassignToCategoryID) yöntemini içeren DAL içinde yardımcı sınıf oluşturmaktır. Bu yöntem CategoriesTableAdapter ve ProductsTableAdapter bir örneğini oluşturur ve sonra bu iki TableAdapters Connection özelliklerini aynı SqlConnection örneğine ayarlar. Bu noktada, iki TableAdapters birini BeginTransactionçağrısı olan işlemi başlatır. Ürünleri yeniden atama ve kategoriyi silme TableAdapters yöntemleri, işlemin yürütüldüğü veya geri alındığı bir Try...Catch bloğunda çağrılır.

4. Adım:UpdateWithTransactionyöntemini Iş mantığı katmanına ekleme

3. adımda, DAL içindeki ProductsTableAdapter bir UpdateWithTransaction yöntemi ekledik. BLL 'ye karşılık gelen bir yöntem ekleyeceğiz. Sunum katmanı UpdateWithTransaction yöntemi çağırmak için doğrudan DAL 'ye çağrı yapmış olsa da bu öğreticiler, sunum katmanından DAL oluşturan katmanlı bir mimari tanımlamaya çalışır. Bu nedenle, behooves bizimle bu yaklaşıma devam etmemizi sağlar.

ProductsBLL sınıf dosyasını açın ve yalnızca karşılık gelen DAL yöntemine çağıran UpdateWithTransaction adlı bir yöntem ekleyin. ProductsBLLŞu anda, yeni eklediğiniz ve adım 3 ' te eklenen DeleteProductsWithTransactionolan UpdateWithTransactioniki yeni yöntem olmalıdır.

Public Function UpdateWithTransaction _
    (ByVal products As Northwind.ProductsDataTable) As Integer
    
    Return Adapter.UpdateWithTransaction(products)
End Function
Public Sub DeleteProductsWithTransaction _
    (ByVal productIDs As System.Collections.Generic.List(Of Integer))
    
    ' Start the transaction
    Adapter.BeginTransaction()
    Try
        ' Delete each product specified in the list
        For Each productID As Integer In productIDs
            Adapter.Delete(productID)
        Next
        ' Commit the transaction
        Adapter.CommitTransaction()
    Catch
        ' There was an error - rollback the transaction
        Adapter.RollbackTransaction()
        Throw
    End Try
End Sub

Note

Bu yöntemler, doğrudan ASP.NET Pages arka plan kod sınıflarından bu yöntemleri çağırabiletireceğiz için ProductsBLL sınıfındaki diğer yöntemlere atanan DataObjectMethodAttribute özniteliğini içermez. Bu DataObjectMethodAttribute, ObjectDataSource 'un veri kaynağını Yapılandır sihirbazında ve hangi sekmenin (SELECT, UPDATE, INSERT veya DELETE) altında görünmesi gerektiğini işaretlemek için kullanıldığını unutmayın. GridView, toplu iş düzenlemesi veya silme için yerleşik bir destek olmadığından, kod içermeyen bildirim yaklaşımını kullanmak yerine bu yöntemleri programlı bir şekilde çağırmamız gerekir.

5. Adım: veritabanı verilerini sunu katmanından otomatik olarak güncelleştirme

İşlemin toplu bir kayıt güncelleştirmesinde olduğu etkiyi göstermek için, bir GridView içindeki tüm ürünleri listeleyen bir kullanıcı arabirimi oluşturun ve tıklandığı zaman, ürün CategoryID değerleri yeniden atar. Özellikle, bazı birkaç ürüne geçerli bir CategoryID değeri atanarak, diğer bir deyişle mevcut olmayan bir CategoryID değerine atanmadığından, kategori yeniden ataması devam edecektir. CategoryID var olan bir CategoryIDkategoriyle eşleşmeyen bir ürünle veritabanını güncelleştirmeye çalışarız, yabancı anahtar kısıtlaması ihlali oluşur ve bir özel durum oluşturulur. Bu örnekte, bir işlem kullanılırken, yabancı anahtar kısıtlaması ihlalinden kaynaklanan özel durum, önceki geçerli CategoryID değişikliklerinin geri alınmasına neden olur. Ancak, bir işlem kullanmadığınız zaman, ilk kategorilerdeki değişiklikler kalır.

Transactions.aspx sayfasını BatchData klasöründen açarak başlatın ve araç kutusundan bir GridView 'ı tasarımcı üzerine sürükleyin. ID Products ve akıllı etiketinden ProductsDataSourceadlı yeni bir ObjectDataSource bağlayın. ProductsBLL sınıf s GetProducts yönteminden verileri çekmek için ObjectDataSource 'ı yapılandırın. Bu, salt okunurdur bir GridView olacaktır, bu nedenle GÜNCELLEŞTIRME, ekleme ve SILME sekmelerinden (yok) açılır listeleri ayarlayın ve son ' a tıklayın.

, ObjectDataSource 'ı ProductsBLL sınıfı s GetProducts metodunu kullanacak şekilde yapılandırma

Şekil 5: ProductsBLL sınıf s GetProducts metodunu (tam boyutlu görüntüyü görüntülemek Için tıklayın) kullanmak üzere ObjectDataSource 'ı yapılandırın

GÜNCELLEŞTIRME, ekleme ve SILME sekmelerindeki açılan listeleri (hiçbiri) ayarla

Şekil 6: GÜNCELLEŞTIRME, ekleme ve silme sekmelerinden açılan listeleri (yok) ayarlayın (tam boyutlu görüntüyü görüntülemek için tıklayın)

Veri kaynağı Yapılandırma Sihirbazı 'nı tamamladıktan sonra, Visual Studio, ürün verileri alanları için BoundFields ve bir CheckBoxField oluşturacaktır. ProductID, ProductName, CategoryIDve CategoryName hariç tüm bu alanları kaldırın ve ProductName ve CategoryName BoundFields HeaderText özellikleri sırasıyla ürün ve kategori olarak yeniden adlandırın. Akıllı etikette, sayfalama etkinleştir seçeneğini işaretleyin. Bu değişiklikleri yaptıktan sonra, GridView ve ObjectDataSource 'lar bildirim temelli biçimlendirme aşağıdaki gibi görünmelidir:

<asp:GridView ID="Products" runat="server" AllowPaging="True" 
    AutoGenerateColumns="False" DataKeyNames="ProductID" 
    DataSourceID="ProductsDataSource">
    <Columns>
        <asp:BoundField DataField="ProductID" HeaderText="ProductID" 
            InsertVisible="False" ReadOnly="True" 
            SortExpression="ProductID" />
        <asp:BoundField DataField="ProductName" HeaderText="Product" 
            SortExpression="ProductName" />
        <asp:BoundField DataField="CategoryID" HeaderText="CategoryID" 
            SortExpression="CategoryID" />
        <asp:BoundField DataField="CategoryName" HeaderText="Category" 
            SortExpression="CategoryName" />
    </Columns>
</asp:GridView>
<asp:ObjectDataSource ID="ProductsDataSource" runat="server" 
    OldValuesParameterFormatString="original_{0}"
    SelectMethod="GetProducts" TypeName="ProductsBLL">
</asp:ObjectDataSource>

Sonra, GridView 'un üstüne üç düğme web denetimi ekleyin. İlk düğme s metin özelliğini kılavuz Yenile, kategorileri değiştirmek için ikinci s (Işlem Ile) ve üçüncü bir tane Kategoriler (Işlem olmadan) olacak şekilde ayarlayın.

<p>
    <asp:Button ID="RefreshGrid" runat="server" Text="Refresh Grid" />
</p>
<p>
    <asp:Button ID="ModifyCategoriesWithTransaction" runat="server"
        Text="Modify Categories (WITH TRANSACTION)" />
</p>
<p>
    <asp:Button ID="ModifyCategoriesWithoutTransaction" runat="server"
        Text="Modify Categories (WITHOUT TRANSACTION)" />
</p>

Bu noktada, Visual Studio 'daki Tasarım görünümü Şekil 7 ' de gösterilen ekran görüntüsüne benzer şekilde görünmelidir.

Sayfada bir GridView ve üç düğme web denetimi Içeren

Şekil 7: sayfa bir GridView ve üç düğme web denetimi içerir (tam boyutlu görüntüyü görüntülemek için tıklayın)

Üç düğme Click olayının her biri için olay işleyicileri oluşturun ve aşağıdaki kodu kullanın:

Protected Sub RefreshGrid_Click _
    (ByVal sender As Object, ByVal e As System.EventArgs) _
    Handles RefreshGrid.Click
    
    Products.DataBind()
End Sub
Protected Sub ModifyCategoriesWithTransaction_Click _
    (ByVal sender As Object, ByVal e As System.EventArgs) _
    Handles ModifyCategoriesWithTransaction.Click
    
    ' Get the set of products
    Dim productsAPI As New ProductsBLL()
    Dim productsData As Northwind.ProductsDataTable = productsAPI.GetProducts()
    ' Update each product's CategoryID
    For Each product As Northwind.ProductsRow In productsData
        product.CategoryID = product.ProductID
    Next
    ' Update the data using a transaction
    productsAPI.UpdateWithTransaction(productsData)
    ' Refresh the Grid
    Products.DataBind()
End Sub
Protected Sub ModifyCategoriesWithoutTransaction_Click _
    (ByVal sender As Object, ByVal e As System.EventArgs) _
    Handles ModifyCategoriesWithoutTransaction.Click
    
    ' Get the set of products
    Dim productsAPI As New ProductsBLL()
    Dim productsData As Northwind.ProductsDataTable = productsAPI.GetProducts()
    ' Update each product's CategoryID
    For Each product As Northwind.ProductsRow In productsData
        product.CategoryID = product.ProductID
    Next
    ' Update the data WITHOUT using a transaction
    Dim productsAdapter As New NorthwindTableAdapters.ProductsTableAdapter()
    productsAdapter.Update(productsData)
    ' Refresh the Grid
    Products.DataBind()
End Sub

Yenileme düğmesi s Click olay işleyicisi, Products GridView s DataBind metodunu çağırarak verileri GridView 'a yeniden bağlar.

İkinci olay işleyicisi, ürünleri CategoryID öğeleri yeniden atar ve bir işlemin şemsiye altında veritabanı güncelleştirmelerini gerçekleştirmek için BLL 'den yeni işlem yöntemini kullanır. Her ürünün CategoryID rastgele ProductIDaynı değere ayarlandığını unutmayın. Bu ürünler geçerli CategoryID s ile eşlenecek ProductID değerler içerdiğinden, ilk birkaç ürün için bu işlem sorunsuz çalışacaktır. Ancak ProductID s çok büyük bir süre sonra başlatıldıktan sonra, ProductID s ve CategoryID s 'nin bu coarızalımesi artık geçerli değildir.

Üçüncü Click olay işleyicisi, ürünleri CategoryID öğeleri aynı şekilde güncelleştirir, ancak ProductsTableAdapter s varsayılan Update yöntemini kullanarak güncelleştirmeyi veritabanına gönderir. Bu Update yöntemi bir işlem içindeki komut serisini sarmaz, bu nedenle bu değişiklikler ilk karşılaşılan yabancı anahtar kısıtlaması ihlali hatası devam edecek.

Bu davranışı göstermek için bu sayfayı bir tarayıcı aracılığıyla ziyaret edin. Başlangıçta, Şekil 8 ' de gösterildiği gibi ilk veri sayfasını görmeniz gerekir. Sonra, kategorileri Değiştir (Işlem Ile) düğmesine tıklayın. Bu, geri göndermeye neden olur ve tüm ürünlerin CategoryID değerlerini güncelleştirmeye çalışır, ancak yabancı anahtar kısıtlaması ihlaline neden olur (bkz. Şekil 9).

ürünleri sayfalanabilir GridView 'da görüntülenir

Şekil 8: ürünler bir sayfalanabilir GridView 'da görüntülenir (tam boyutlu görüntüyü görüntülemek için tıklayın)

Kategoriler bir yabancı anahtar kısıtlaması Ihlaline neden olur

Şekil 9: kategorileri yeniden atama yabancı anahtar kısıtlaması ihlaline neden olur (tam boyutlu görüntüyü görüntülemek için tıklayın)

Şimdi tarayıcı geri düğmesine basın ve ardından kılavuza Yenile düğmesine tıklayın. Verileri yenilemeden sonra, Şekil 8 ' de gösterildiği gibi tam olarak aynı çıktıyı görmeniz gerekir. Diğer bir deyişle, bazı CategoryID ürünlerden bazıları yasal değerler olarak değiştirilse ve veritabanında güncelleştirilene karşın, yabancı anahtar kısıtlaması ihlali oluştuğunda geri alınır.

Şimdi kategorileri Değiştir (Işlem olmadan) düğmesini tıklatmaya çalışın. Bu, aynı yabancı anahtar kısıtlaması ihlali hatasına neden olur (bkz. Şekil 9), ancak bu sefer CategoryID değerleri geçerli bir değer olarak değiştirilen ürünler geri alınmaz. Tarayıcınızın geri düğmesine ve ardından Kılavuz Yenile düğmesine basın. Şekil 10 ' da gösterildiği gibi, ilk sekiz ürünün CategoryID s ' i yeniden atandı. Örneğin, Şekil 8 ' de, Chang 1 ' in CategoryID vardı, ancak Şekil 10 ' da 2 ' ye yeniden atandı.

bazı ürünlerin CategoryID değerlerinin güncelleştirildiği sırada güncelleştirilmiş olması

Şekil 10: bazı ürün CategoryID değerleri, diğerleri oluşturulmazken güncelleştirildi (tam boyutlu görüntüyü görüntülemek için tıklayın)

Özet

Varsayılan olarak, TableAdapter s yöntemleri yürütülen veritabanı deyimlerini bir işlemin kapsamı içinde sarmaz, ancak küçük bir çalışmalarla bir işlem oluşturacak, kaydedilecek ve geri alacak Yöntemler ekleyebiliriz. Bu öğreticide ProductsTableAdapter sınıfında üç tür yöntem oluşturduk: BeginTransaction, CommitTransactionve RollbackTransaction. Bu yöntemlerin bir dizi veri değiştirme deyimini atomik hale getirmek için bir Try...Catch bloğuyla birlikte nasıl kullanılacağını gördük. Özellikle, sağlanan bir ProductsDataTablesatırlarda gerekli değişiklikleri gerçekleştirmek için Batch güncelleştirme modelini kullanan ProductsTableAdapter``UpdateWithTransaction yöntemi oluşturduk. Ayrıca, DeleteProductsWithTransaction yöntemini, giriş olarak ProductID değerleri List kabul eden ve her Delete için DB-Direct model yöntemini çağıran BLL içindeki ProductsBLL sınıfına ekledik.ProductID Her iki yöntem de bir işlem oluşturarak ve sonra veri değiştirme deyimlerini bir Try...Catch bloğu içinde yürütülerek başlar. Bir özel durum oluşursa, işlem geri alınır, aksi takdirde işlenir.

5. adım, işlem toplu iş güncelleştirmelerinin bir işlem kullanmak için ihmal edilen toplu güncelleştirmeler ile ilgili etkisini Sonraki üç öğreticide, bu öğreticide bulunan temel üzerine oluşturacağız ve toplu güncelleştirme, silme ve ekleme işlemlerini gerçekleştirmek için Kullanıcı arabirimleri oluşturacağız.

Programlamanın kutlu olsun!

Daha Fazla Bilgi

Bu öğreticide ele alınan konular hakkında daha fazla bilgi için aşağıdaki kaynaklara bakın:

Yazar hakkında

4GuysFromRolla.com 'in, Scott Mitchell, yedi ASP/ASP. net books ve 'in yazarı, 1998 sürümünden bu yana Microsoft Web teknolojileriyle çalışmaktadır. Scott bağımsız danışman, Trainer ve yazıcı olarak çalışıyor. En son kitabı, 24 saat içinde ASP.NET 2,0 kendi kendinize eğitimister. mitchell@4GuysFromRolla.comadresinden erişilebilir . ya da blog aracılığıyla http://ScottOnWriting.NETbulabilirsiniz.

Özel olarak teşekkürler

Bu öğretici serisi birçok yararlı gözden geçirenler tarafından incelendi. Bu öğreticide lider gözden geçirenler, Gardner, Tepton Giesenow ve Teresa Murphy. Yaklaşan MSDN makalelerimi gözden geçiriyor musunuz? Öyleyse, benimitchell@4GuysFromRolla.combir satır bırakın .