Bagikan melalui


Penyisipan Batch (VB)

oleh Scott Mitchell

Unduh PDF

Pelajari cara menyisipkan beberapa rekaman database dalam satu operasi. Di Lapisan Antarmuka Pengguna, kami memperluas GridView untuk memungkinkan pengguna memasukkan beberapa rekaman baru. Di Lapisan Akses Data, kami menggabungkan beberapa operasi penyisipan data dalam satu transaksi untuk memastikan bahwa semua penyisipan data berhasil atau semua penyisipan dibatalkan.

Pendahuluan

Dalam tutorial Pembaruan Batch, kami membahas penyesuaian kontrol GridView untuk menyajikan antarmuka di mana beberapa rekaman dapat diedit. Pengguna yang mengunjungi halaman dapat membuat serangkaian perubahan lalu, dengan satu klik tombol, melakukan pembaruan batch. Untuk situasi di mana pengguna biasanya memperbarui banyak rekaman dalam sekali jalan, antarmuka seperti itu dapat menyimpan klik yang tak terhitung jumlahnya dan pengalihan konteks keyboard-ke-mouse jika dibandingkan dengan fitur pengeditan per baris default yang pertama kali dijelajahi kembali dalam tutorial Gambaran Umum Menyisipkan, Memperbarui, dan Menghapus Data .

Konsep ini juga dapat diterapkan saat menambahkan rekaman. Bayangkan bahwa di sini di Northwind Traders kami biasanya menerima pengiriman dari pemasok yang berisi sejumlah produk untuk kategori tertentu. Sebagai contoh, kami mungkin menerima pengiriman enam produk teh dan kopi yang berbeda dari Tokyo Traders. Jika pengguna memasukkan enam produk satu per satu melalui kontrol DetailsView, mereka harus memilih banyak nilai yang sama berulang kali: mereka harus memilih kategori yang sama (Minuman), pemasok yang sama (Tokyo Traders), nilai yang dihentikan yang sama (Salah), dan unit yang sama pada nilai pesanan (0). Entri data berulang ini tidak hanya memakan waktu, tetapi rentan terhadap kesalahan.

Dengan sedikit pekerjaan, kita dapat membuat antarmuka penyisipan batch yang memungkinkan pengguna memilih pemasok dan kategori sekali, memasukkan serangkaian nama produk dan harga unit, lalu mengklik tombol untuk menambahkan produk baru ke database (lihat Gambar 1). Saat setiap produk ditambahkan, ProductName dan UnitPrice bidang datanya diberi nilai yang dimasukkan di Kotak Teks, sementara nilai-nilainya CategoryID dan SupplierID ditetapkan dari DropDownLists di bagian atas formulir. Nilai Discontinued dan UnitsOnOrder diatur ke nilai yang dikodekan keras yaitu False dan 0, masing-masing.

Antarmuka Penyisipan Kelompok

Gambar 1: Antarmuka Penyisipan Batch (Klik untuk melihat gambar ukuran penuh)

Dalam tutorial ini kita akan membuat halaman yang mengimplementasikan antarmuka penyisipan batch yang ditunjukkan pada Gambar 1. Seperti dua tutorial sebelumnya, kami akan mengemas penyisipan dalam lingkup transaksi untuk memastikan atomisitas. Mari kita mulai!

Langkah 1: Membuat Antarmuka Tampilan

Tutorial ini akan terdiri dari satu halaman yang dibagi menjadi dua wilayah: wilayah tampilan dan wilayah penyisipan. Antarmuka tampilan, yang akan kita buat dalam langkah ini, menunjukkan produk dalam GridView dan menyertakan tombol berjudul Proses Pengiriman Produk. Ketika tombol ini diklik, antarmuka tampilan diganti dengan antarmuka penyisipan, yang ditampilkan dalam Gambar 1. Antarmuka tampilan kembali setelah tombol Tambahkan Produk dari Pengiriman atau Batal diklik. Kita akan membuat antarmuka penyisipan di Langkah 2.

Saat membuat halaman yang memiliki dua antarmuka, hanya satu yang terlihat pada satu waktu, setiap antarmuka biasanya ditempatkan dalam kontrol Web Panel, yang berfungsi sebagai kontainer untuk kontrol lain. Oleh karena itu, halaman kami akan memiliki dua kontrol Panel satu untuk setiap antarmuka.

Mulailah dengan membuka BatchInsert.aspx halaman di BatchData folder dan seret Panel dari Kotak Alat ke Perancang (lihat Gambar 2). Atur properti Panel ID ke DisplayInterface. Saat menambahkan Panel ke Perancang, properti Height dan Width ditetapkan masing-masing ke 50px dan 125px. Hapus nilai properti ini dari jendela Properti.

Seret Panel dari Kotak Alat ke Perancang

Gambar 2: Seret Panel dari Kotak Alat ke Perancang (Klik untuk melihat gambar ukuran penuh)

Selanjutnya, seret kontrol Tombol dan GridView ke panel. Atur properti ID Tombol ke ProcessShipment dan properti Text ke Proses Pengiriman Produk. Atur properti GridView ke IDProductsGrid dan, dari tag pintarnya, ikat ke ObjectDataSource baru bernama ProductsDataSource. Konfigurasikan ObjectDataSource untuk mengambil data dari metode kelas ProductsBLL dan GetProducts. Karena GridView ini hanya digunakan untuk menampilkan data, atur daftar drop-down di tab PERBARUI, SISIPKAN, dan HAPUS ke (Tidak Ada). Klik Selesai untuk menyelesaikan wizard Konfigurasi Sumber Data.

Memperlihatkan Data yang Dikembalikan oleh Metode GetProducts dari Kelas ProductsBLL

Gambar 3: Menampilkan data yang dikembalikan dari metode kelas ProductsBLLGetProducts (Klik untuk melihat gambar ukuran penuh)

Atur Daftar Drop-Down di Tab PERBARUI, SISIPKAN, dan HAPUS menjadi Tidak Ada

Gambar 4: Atur Daftar Drop-Down di Tab PERBARUI, SISIPKAN, dan HAPUS ke (Tidak Ada) (Klik untuk melihat gambar ukuran penuh)

Setelah menyelesaikan wizard ObjectDataSource, Visual Studio akan menambahkan BoundFields dan CheckBoxField untuk bidang data produk. Hapus semua kecuali bidang ProductName, CategoryName, SupplierName, UnitPrice, dan Discontinued. Jangan ragu untuk membuat penyesuaian estetika. Saya memutuskan untuk memformat UnitPrice bidang sebagai nilai mata uang, menyusun ulang bidang, dan mengganti nama beberapa nilai bidang HeaderText . Konfigurasikan juga GridView agar mencakup dukungan penghalaman dan pengurutan dengan mencentang kotak pilihan "Aktifkan Penghalaman" dan "Aktifkan Pengurutan" pada tag pintar GridView.

Setelah menambahkan kontrol Panel, Tombol, GridView, dan ObjectDataSource dan menyesuaikan bidang GridView, markup deklaratif halaman Anda akan terlihat mirip dengan yang berikut ini:

<asp:Panel ID="DisplayInterface" runat="server">
    <p>
        <asp:Button ID="ProcessShipment" runat="server" 
            Text="Process Product Shipment" /> 
    </p>
    <asp:GridView ID="ProductsGrid" runat="server" AllowPaging="True" 
        AllowSorting="True" AutoGenerateColumns="False" 
        DataKeyNames="ProductID" DataSourceID="ProductsDataSource">
        <Columns>
            <asp:BoundField DataField="ProductName" HeaderText="Product" 
                SortExpression="ProductName" />
            <asp:BoundField DataField="CategoryName" HeaderText="Category" 
                ReadOnly="True" SortExpression="CategoryName" />
            <asp:BoundField DataField="SupplierName" HeaderText="Supplier" 
                ReadOnly="True" SortExpression="SupplierName" />
            <asp:BoundField DataField="UnitPrice" DataFormatString="{0:c}" 
                HeaderText="Price" HtmlEncode="False" 
                SortExpression="UnitPrice">
                <ItemStyle HorizontalAlign="Right" />
            </asp:BoundField>
            <asp:CheckBoxField DataField="Discontinued" HeaderText="Discontinued" 
                SortExpression="Discontinued">
                <ItemStyle HorizontalAlign="Center" />
            </asp:CheckBoxField>
        </Columns>
    </asp:GridView>
    <asp:ObjectDataSource ID="ProductsDataSource" runat="server" 
        OldValuesParameterFormatString="original_{0}"
        SelectMethod="GetProducts" TypeName="ProductsBLL">
    </asp:ObjectDataSource>
</asp:Panel>

Perhatikan bahwa markup untuk Tombol dan GridView muncul dalam tag pembuka dan penutupan <asp:Panel> . Karena kontrol ini berada di DisplayInterface dalam Panel, kita dapat menyembunyikannya hanya dengan mengatur properti Panel Visible ke False. Langkah 3 berfokus pada mengubah properti Panel secara programatis sebagai respons terhadap klik tombol untuk menampilkan satu antarmuka dan menyembunyikan antarmuka yang lain.

Luangkan waktu sejenak untuk melihat kemajuan kami melalui browser. Seperti yang ditunjukkan Gambar 5, Anda akan melihat tombol Pengiriman Produk Proses di atas GridView yang mencantumkan produk sepuluh sekaligus.

GridView Mencantumkan Produk dan Memungkinkan Pengurutan dan Penomoran

Gambar 5: GridView Mencantumkan Kemampuan Pengurutan dan Penomoran Produk dan Penawaran (Klik untuk melihat gambar ukuran penuh)

Langkah 2: Membuat Antarmuka Penyisipan

Dengan antarmuka tampilan selesai, kami siap untuk membuat antarmuka penyisipan. Untuk tutorial ini, mari kita buat antarmuka penyisipan yang meminta satu pemasok dan nilai kategori dan kemudian memungkinkan pengguna untuk memasukkan hingga lima nama produk dan nilai harga satuan. Dengan antarmuka ini, pengguna dapat menambahkan satu hingga lima produk baru yang semuanya memiliki kategori dan pemasok yang sama, tetapi memiliki nama dan harga produk yang unik.

Mulailah dengan menyeret Panel dari Kotak Alat ke Perancang, menempatkannya di bawah Panel DisplayInterface yang ada. Atur ID properti Panel yang baru ditambahkan ini ke InsertingInterface dan atur propertinya Visible ke False. Kami akan menambahkan kode yang mengatur InsertingInterface properti Panel Visible ke True di Langkah 3. Hapus juga nilai properti dalam Panel Height dan Width.

Selanjutnya, kita perlu membuat antarmuka penyisipan yang ditampilkan kembali di Gambar 1. Antarmuka ini dapat dibuat melalui berbagai teknik HTML, tetapi kita akan menggunakan yang cukup mudah: tabel empat kolom tujuh baris.

Nota

Saat memasukkan markup untuk elemen HTML <table> , saya lebih suka menggunakan tampilan Sumber. Meskipun Visual Studio memang memiliki alat untuk menambahkan elemen <table> melalui Perancang, Perancang tampaknya terlalu bersedia untuk menyuntikkan pengaturan style yang tidak diminta ke dalam markup. Setelah saya membuat <table> markup, saya biasanya kembali ke Perancang untuk menambahkan kontrol Web dan mengatur propertinya. Saat membuat tabel dengan kolom dan baris yang telah ditentukan sebelumnya, saya lebih suka menggunakan HTML statis daripada kontrol Web Tabel karena kontrol Web apa pun yang ditempatkan dalam kontrol Web Tabel hanya dapat diakses menggunakan FindControl("controlID") pola . Namun, saya menggunakan kontrol Web Tabel untuk tabel berukuran dinamis (yang baris atau kolomnya didasarkan pada beberapa database atau kriteria yang ditentukan pengguna), karena kontrol Web Tabel dapat dibangun secara terprogram.

Letakkan markup berikut di dalam tag <asp:Panel> pada Panel InsertingInterface.

<table class="DataWebControlStyle" cellspacing="0">
    <tr class="BatchInsertHeaderRow">
        <td class="BatchInsertLabel">Supplier:</td>
        <td></td>
        <td class="BatchInsertLabel">Category:</td>
        <td></td>
    </tr>
    <tr class="BatchInsertRow">
        <td class="BatchInsertLabel">Product:</td>
        <td></td>
        <td class="BatchInsertLabel">Price:</td>
        <td></td>
    </tr>
    <tr class="BatchInsertAlternatingRow">
        <td class="BatchInsertLabel">Product:</td>
        <td></td>
        <td class="BatchInsertLabel">Price:</td>
        <td></td>
    </tr>
    <tr class="BatchInsertRow">
        <td class="BatchInsertLabel">Product:</td>
        <td></td>
        <td class="BatchInsertLabel">Price:</td>
        <td></td>
    </tr>
    <tr class="BatchInsertAlternatingRow">
        <td class="BatchInsertLabel">Product:</td>
        <td></td>
        <td class="BatchInsertLabel">Price:</td>
        <td></td>
    </tr>
    <tr class="BatchInsertRow">
        <td class="BatchInsertLabel">Product:</td>
        <td></td>
        <td class="BatchInsertLabel">Price:</td>
        <td></td>
    </tr>
    <tr class="BatchInsertFooterRow">
        <td colspan="4">
        </td>
    </tr>
</table>

Markup ini <table> belum menyertakan kontrol Web apa pun, kami akan menambahkannya sesaat. Perhatikan bahwa setiap elemen <tr> berisi pengaturan kelas CSS tertentu: BatchInsertHeaderRow untuk baris header tempat DropDownList pemasok dan kategori berada; BatchInsertFooterRow untuk baris footer tempat Tombol Tambahkan Produk dari Pengiriman dan Batalkan berada; dan nilai berganti-ganti BatchInsertRow dan BatchInsertAlternatingRow untuk baris yang akan berisi kontrol TextBox harga satuan dan produk. Saya telah membuat kelas CSS yang sesuai dalam Styles.css file untuk memberikan antarmuka penyisipan tampilan yang mirip dengan kontrol GridView dan DetailsView yang telah kami gunakan di seluruh tutorial ini. Kelas CSS ini ditunjukkan di bawah ini.

/*** Styles for ~/BatchData/BatchInsert.aspx tutorial ***/
.BatchInsertLabel
{
    font-weight: bold;
    text-align: right;
}
.BatchInsertHeaderRow td
{
    color: White;
    background-color: #900;
    padding: 11px;
}
.BatchInsertFooterRow td
{
    text-align: center;
    padding-top: 5px;
}
.BatchInsertRow
{
}
.BatchInsertAlternatingRow
{
    background-color: #fcc;
}

Dengan markup ini dimasukkan, kembali ke tampilan Desain. Ini <table> akan ditampilkan sebagai tabel empat kolom tujuh baris di Desainer, seperti yang diilustrasikan Gambar 6 itu.

Antarmuka Penyisipan Terdiri dari Tabel Empat Kolom, Seven-Row

Gambar 6: Antarmuka Penyisipan Terdiri dari Empat Kolom, Seven-Row Tabel (Klik untuk melihat gambar ukuran penuh)

Kami sekarang siap untuk menambahkan kontrol Web ke antarmuka penyisipan. Seret dua DropDownList dari Kotak Alat ke dalam sel yang sesuai dalam tabel, satu untuk pemasok dan satu untuk kategori.

Atur properti DropDownList ID pemasok ke Suppliers dan ikat ke ObjectDataSource baru bernama SuppliersDataSource. Konfigurasikan ObjectDataSource baru untuk mengambil datanya dari metode kelas SuppliersBLL dan kemudian atur daftar drop-down tab UPDATE ke (Tidak Ada). Klik Selesai untuk menyelesaikan wizard.

Konfigurasi ObjectDataSource untuk menggunakan metode GetSuppliers dari kelas SuppliersBLL

Gambar 7: Konfigurasikan ObjectDataSource untuk Menggunakan Metode dari Kelas SuppliersBLLGetSuppliers (Klik untuk melihat gambar ukuran penuh)

Suppliers Minta DropDownList menampilkan CompanyName bidang data dan gunakan SupplierID bidang data sebagai ListItem nilainya.

Tampilkan Bidang Data CompanyName dan Gunakan SupplierID sebagai Nilai

Gambar 8: Tampilkan CompanyName Bidang Data dan Gunakan SupplierID sebagai Nilai (Klik untuk melihat gambar ukuran penuh)

Beri nama DropDownList Categories kedua dan ikat ke ObjectDataSource baru bernama CategoriesDataSource. Konfigurasikan ObjectDataSource CategoriesDataSource untuk menggunakan metode CategoriesBLL dari kelas GetCategories; atur daftar drop-down di tab PERBARUI dan HAPUS ke (Tidak Ada) dan klik Selesai untuk menyelesaikan pengaturan wizard. Terakhir, minta DropDownList menampilkan CategoryName bidang data dan gunakan CategoryID sebagai nilai.

Setelah kedua DropDownList ini ditambahkan dan terikat ke ObjectDataSources yang dikonfigurasi dengan tepat, layar Anda akan terlihat mirip dengan Gambar 9.

Baris Header Sekarang Berisi Daftar DropDown Pemasok dan Kategori

Gambar 9: Baris Header Sekarang Berisi Suppliers dan Categories DropDownLists (Klik untuk melihat gambar ukuran penuh)

Kita sekarang perlu membuat TextBoxes untuk mengumpulkan nama dan harga untuk setiap produk baru. Seret kontrol TextBox dari Kotak Alat ke Desainer untuk setiap dari lima baris nama produk dan harga. Atur ID properti Kotak Teks ke ProductName1, , UnitPrice1, ProductName2UnitPrice2, ProductName3, UnitPrice3, dan sebagainya.

Tambahkan CompareValidator setelah setiap kotak teks harga satuan, lalu atur properti ControlToValidate ke ID yang sesuai. Atur juga properti Operator ke GreaterThanEqual, ValueToCompare ke 0, dan Type ke Currency. Pengaturan ini menginstruksikan CompareValidator untuk memastikan bahwa harga, jika dimasukkan, adalah nilai mata uang yang valid yang lebih besar dari atau sama dengan nol. Atur Text properti ke *, dan ErrorMessage ke Harga harus lebih besar dari atau sama dengan nol. Selain itu, silakan hilangkan simbol mata uang apa pun.

Nota

Antarmuka penyisipan tidak menyertakan kontrol-kontrol RequiredFieldValidator, meskipun di ProductName tabel basis data, bidang Products tidak mengizinkan nilai NULL. Ini karena kami ingin membiarkan pengguna memasukkan hingga lima produk. Misalnya, jika pengguna memberikan nama produk dan harga satuan untuk tiga baris pertama, membiarkan dua baris terakhir kosong, kami hanya menambahkan tiga produk baru ke sistem. Karena ProductName diperlukan, bagaimanapun, kita perlu memeriksa secara terprogram untuk memastikan bahwa jika harga satuan dimasukkan bahwa nilai nama produk yang sesuai disediakan. Kami akan mengatasi pemeriksaan ini di Langkah 4.

Saat memvalidasi input pengguna, CompareValidator melaporkan data yang tidak valid jika nilai berisi simbol mata uang. Tambahkan $ di depan setiap harga satuan TextBoxes untuk berfungsi sebagai isjin visual yang menginstruksikan pengguna untuk menghilangkan simbol mata uang saat memasukkan harga.

Terakhir, tambahkan kontrol ValidationSummary ke dalam InsertingInterface Panel, atur properti ShowMessageBox ke True dan properti ShowSummary ke False. Dengan pengaturan ini, jika pengguna memasukkan nilai harga unit yang tidak valid, tanda bintang akan muncul di samping kontrol TextBox yang menyinggung dan ValidationSummary akan menampilkan kotak pesan sisi klien yang menunjukkan pesan kesalahan yang kami tentukan sebelumnya.

Pada titik ini, layar Anda akan terlihat mirip dengan Gambar 10.

Antarmuka Penyisipan Sekarang Mencakup Kotak Teks untuk Nama dan Harga Produk

Gambar 10: Antarmuka Penyisipan Sekarang Menyertakan Kotak Teks untuk Nama dan Harga Produk (Klik untuk melihat gambar ukuran penuh)

Selanjutnya kita perlu menambahkan tombol Tambahkan Produk dari Pengiriman dan Batalkan ke baris footer. Seret dua kontrol Tombol dari Kotak Alat ke footer antarmuka penyisipan, atur properti Tombol ID ke AddProducts dan CancelButton dan Text properti masing-masing ke Tambahkan Produk dari Pengiriman dan Batalkan. Selain itu, atur properti kontrol CancelButton s CausesValidation ke false.

Terakhir, kita perlu menambahkan kontrol Web Label yang akan menampilkan pesan status untuk dua antarmuka. Misalnya, ketika pengguna berhasil menambahkan pengiriman produk baru, kami ingin kembali ke antarmuka tampilan dan menampilkan pesan konfirmasi. Namun, jika pengguna memberikan harga untuk produk baru tetapi meninggalkan nama produk, kita perlu menampilkan pesan peringatan karena ProductName bidang diperlukan. Karena kita memerlukan pesan ini untuk ditampilkan untuk kedua antarmuka, letakkan di bagian atas halaman di luar Panel.

Seret kontrol Label Web dari Kotak Alat ke bagian atas halaman di Perancang. Atur ID properti ke StatusLabel, hapus Text properti, dan atur Visible properti dan EnableViewState ke False. Seperti yang telah kita lihat dalam tutorial sebelumnya, mengatur EnableViewState properti ke False memungkinkan kita untuk secara terprogram mengubah nilai-nilai properti Label dan secara otomatis mengembalikannya ke nilai default pada postback berikutnya. Ini menyederhanakan kode untuk menampilkan pesan status sebagai respons terhadap beberapa tindakan pengguna yang menghilang pada postback berikutnya. Terakhir, tetapkan properti StatusLabel kontrol menjadi CssClass Peringatan, yang merupakan nama kelas CSS yang ditentukan dalam Styles.css dan menampilkan teks dengan font yang besar, miring, tebal, serta berwarna merah.

Gambar 11 memperlihatkan Visual Studio Designer setelah Label ditambahkan dan dikonfigurasi.

Tempatkan Kontrol StatusLabel di Atas Kontrol Dua Panel

Gambar 11: Tempatkan StatusLabel Kontrol di Atas Kontrol Dua Panel (Klik untuk melihat gambar ukuran penuh)

Langkah 3: Beralih Antara Tampilan dan Menyisipkan Antarmuka

Pada titik ini kami telah menyelesaikan markup untuk tampilan dan menyisipkan antarmuka kami, tetapi kami masih tersisa dengan dua tugas:

  • Beralih antara tampilan dan menyisipkan antarmuka
  • Menambahkan produk dalam pengiriman ke database

Saat ini, antarmuka tampilan terlihat tetapi antarmuka penyisipan disembunyikan. Ini karena properti Panel DisplayInterface diatur ke Visible (nilai default), sementara properti Panel True diatur ke InsertingInterface. Untuk beralih di antara dua antarmuka, kita hanya perlu mengalihkan setiap nilai properti kontrol Visible .

Kami ingin berpindah dari antarmuka tampilan ke antarmuka penyisipan saat tombol Proses Pengiriman Produk diklik. Oleh karena itu, buat penanganan aktivitas untuk peristiwa Tombol ini Click yang berisi kode berikut:

Protected Sub ProcessShipment_Click(sender As Object, e As EventArgs) _
    Handles ProcessShipment.Click
    DisplayInterface.Visible = False
    InsertingInterface.Visible = True
End Sub

Kode ini hanya menyembunyikan DisplayInterface Panel dan menunjukkan InsertingInterface Panel.

Selanjutnya, buat penanganan aktivitas untuk kontrol Tambahkan Produk dari Pengiriman dan Batalkan Tombol di antarmuka penyisipan. Ketika salah satu Tombol ini diklik, kita perlu kembali ke antarmuka tampilan. Buat Click penanganan aktivitas untuk kedua kontrol Tombol sehingga mereka memanggil ReturnToDisplayInterface, metode yang akan kita tambahkan sesaat. Selain menyembunyikan InsertingInterface Panel dan menampilkan DisplayInterface Panel, ReturnToDisplayInterface metode ini perlu mengembalikan kontrol Web ke status pra-pengeditannya. Ini melibatkan pengaturan properti DropDownLists SelectedIndex ke 0 dan menghapus Text properti kontrol TextBox.

Nota

Pertimbangkan apa yang mungkin terjadi jika kami tidak mengembalikan kontrol ke status pra-pengeditan sebelum kembali ke antarmuka tampilan. Pengguna dapat mengklik tombol Proses Pengiriman Produk, memasukkan produk dari pengiriman, lalu klik Tambahkan Produk dari Pengiriman. Ini akan menambahkan produk dan mengembalikan pengguna ke antarmuka tampilan. Pada titik ini pengguna mungkin ingin menambahkan pengiriman lain. Setelah mengklik tombol Pengiriman Produk Proses, mereka akan kembali ke antarmuka penyisipan tetapi pilihan DropDownList dan nilai TextBox masih akan diisi dengan nilai sebelumnya.

Protected Sub AddProducts_Click(sender As Object, e As EventArgs) _
    Handles AddProducts.Click
    ' TODO: Save the products
    ' Revert to the display interface
    ReturnToDisplayInterface()
End Sub
Protected Sub CancelButton_Click(sender As Object, e As EventArgs) _
    Handles CancelButton.Click
    ' Revert to the display interface
    ReturnToDisplayInterface()
End Sub
Const firstControlID As Integer = 1
Const lastControlID As Integer = 5
Private Sub ReturnToDisplayInterface()
    ' Reset the control values in the inserting interface
    Suppliers.SelectedIndex = 0
    Categories.SelectedIndex = 0
    For i As Integer = firstControlID To lastControlID
        CType(InsertingInterface.FindControl _
            ("ProductName" + i.ToString()), TextBox).Text = String.Empty
        CType(InsertingInterface.FindControl _
            ("UnitPrice" + i.ToString()), TextBox).Text = String.Empty
    Next
    DisplayInterface.Visible = True
    InsertingInterface.Visible = False
End Sub

Kedua Click penanganan aktivitas hanya memanggil ReturnToDisplayInterface metode , meskipun kita akan kembali ke penanganan aktivitas Tambahkan Produk dari Pengiriman Click di Langkah 4 dan menambahkan kode untuk menyimpan produk. ReturnToDisplayInterface dimulai dengan mengembalikan Suppliers dan Categories DropDownLists ke opsi pertamanya. Dua konstanta firstControlID dan lastControlID menandai nilai indeks kontrol awal dan akhir yang digunakan untuk penamaan pada kotak teks untuk nama produk dan harga satuan dalam antarmuka penambahan, dan digunakan sebagai batas dalam perulangan For yang mengatur properti Text kontrol TextBox kembali ke string kosong. Terakhir, properti Panel Visible diatur ulang sehingga antarmuka penyisipan disembunyikan dan antarmuka tampilan ditampilkan.

Luangkan waktu sejenak untuk menguji halaman ini di browser. Ketika pertama kali mengunjungi halaman, Anda akan melihat antarmuka tampilan seperti yang ditunjukkan pada Gambar 5. Klik tombol Proses Pengiriman Produk. Halaman akan memuat ulang dan Anda sekarang akan melihat antarmuka penyisipan seperti yang ditunjukkan pada Gambar 12. Mengklik tombol Tambahkan Produk dari Pengiriman atau Batal mengembalikan Anda ke antarmuka tampilan.

Nota

Saat melihat antarmuka penyisipan, luangkan waktu sejenak untuk menguji CompareValidators pada Kotak Teks harga satuan. Anda akan melihat peringatan kotak pesan sisi klien saat mengklik tombol Tambahkan Produk dari Pengiriman dengan nilai mata uang atau harga yang tidak valid dengan nilai kurang dari nol.

Antarmuka Penyisipan Ditampilkan Setelah Mengklik Tombol Proses Pengiriman Produk

Gambar 12: Antarmuka Penyisipan Ditampilkan Setelah Mengklik Tombol Proses Pengiriman Produk (Klik untuk melihat gambar ukuran penuh)

Langkah 4: Menambahkan Produk

Semua yang tersisa untuk tutorial ini adalah menyimpan produk ke database di penanganan aktivitas Tambahkan Produk dari Tombol Click Pengiriman. Ini dapat dicapai dengan membuat ProductsDataTable dan menambahkan ProductsRow instans untuk setiap nama produk yang disediakan. Setelah ProductsRow ini ditambahkan, kami akan memanggil metode kelas ProductsBLL pada UpdateWithTransaction dengan melewatkan ProductsDataTable. Ingat bahwa metode UpdateWithTransaction, yang dibuat pada tutorial Modifikasi Pembungkusan Basis Data dalam Transaksi, meneruskan ProductsDataTable ke metode ProductsTableAdapter dari UpdateWithTransaction. Dari sana, transaksi ADO.NET dimulai dan TableAdapter mengeluarkan pernyataan INSERT ke database untuk setiap ProductsRow yang ditambahkan ke dalam DataTable. Dengan asumsi semua produk ditambahkan tanpa kesalahan, transaksi dikomit, jika tidak, dibatalkan.

Kode untuk penanganan aktivitas Tambahkan Produk dari Tombol Click Pengiriman juga perlu melakukan sedikit pemeriksaan kesalahan. Karena tidak ada RequiredFieldValidators yang digunakan dalam antarmuka penyisipan, pengguna dapat memasukkan harga untuk produk sambil menghilangkan namanya. Karena nama produk diperlukan, jika kondisi seperti itu terjadi, kita perlu memberi tahu pengguna dan tidak melanjutkan dengan penyisipan data. Kode penanganan aktivitas lengkap Click mengikuti:

Protected Sub AddProducts_Click(sender As Object, e As EventArgs) _
    Handles AddProducts.Click
    ' Make sure that the UnitPrice CompareValidators report valid data...
    If Not Page.IsValid Then Exit Sub
    ' Add new ProductsRows to a ProductsDataTable...
    Dim products As New Northwind.ProductsDataTable()
    For i As Integer = firstControlID To lastControlID
        ' Read in the values for the product name and unit price
        Dim productName As String = CType(InsertingInterface.FindControl _
            ("ProductName" + i.ToString()), TextBox).Text.Trim()
        Dim unitPrice As String = CType(InsertingInterface.FindControl _
            ("UnitPrice" + i.ToString()), TextBox).Text.Trim()
        ' Ensure that if unitPrice has a value, so does productName
        If unitPrice.Length > 0 AndAlso productName.Length = 0 Then
            ' Display a warning and exit this event handler
            StatusLabel.Text = "If you provide a unit price you must also 
                                include the name of the product."
            StatusLabel.Visible = True
            Exit Sub
        End If
        ' Only add the product if a product name value is provided
        If productName.Length > 0 Then
            ' Add a new ProductsRow to the ProductsDataTable
            Dim newProduct As Northwind.ProductsRow = products.NewProductsRow()
            ' Assign the values from the web page
            newProduct.ProductName = productName
            newProduct.SupplierID = Convert.ToInt32(Suppliers.SelectedValue)
            newProduct.CategoryID = Convert.ToInt32(Categories.SelectedValue)
            If unitPrice.Length > 0 Then
                newProduct.UnitPrice = Convert.ToDecimal(unitPrice)
            End If
            ' Add any "default" values
            newProduct.Discontinued = False
            newProduct.UnitsOnOrder = 0
            products.AddProductsRow(newProduct)
        End If
    Next
    ' If we reach here, see if there were any products added
    If products.Count > 0 Then
        ' Add the new products to the database using a transaction
        Dim productsAPI As New ProductsBLL()
        productsAPI.UpdateWithTransaction(products)
        ' Rebind the data to the grid so that the products just added are displayed
        ProductsGrid.DataBind()
        ' Display a confirmation (don't use the Warning CSS class, though)
        StatusLabel.CssClass = String.Empty
        StatusLabel.Text = String.Format( _
            "{0} products from supplier {1} have been " & _
            "added and filed under category {2}.", _
            products.Count, Suppliers.SelectedItem.Text, Categories.SelectedItem.Text)
        StatusLabel.Visible = True
        ' Revert to the display interface
        ReturnToDisplayInterface()
    Else
        ' No products supplied!
        StatusLabel.Text = 
            "No products were added. Please enter the " & _
            "product names and unit prices in the textboxes."
        StatusLabel.Visible = True
    End If
End Sub

Penanganan aktivitas dimulai dengan memastikan bahwa Page.IsValid properti mengembalikan nilai True. Jika mengembalikan False, itu menunjukkan bahwa satu atau beberapa CompareValidators melaporkan data yang tidak valid; dalam kasus seperti itu, kami tidak ingin mencoba memasukkan produk yang telah diinputkan atau kami akan menghadapi pengecualian saat mencoba menetapkan nilai harga unit yang dimasukkan pengguna ke properti ProductsRow dari UnitPrice.

Selanjutnya, instans baru ProductsDataTable dibuat (products). Perulangan For digunakan untuk iterasi melalui kotak teks nama produk dan harga satuan, kemudian properti Text dibaca ke dalam variabel lokal productName dan unitPrice. Jika pengguna telah memasukkan nilai untuk harga satuan tetapi tidak untuk nama produk yang sesuai, StatusLabel menampilkan pesan Jika Anda memberikan harga satuan, Anda juga harus menyertakan nama produk dan penangan kejadian dihentikan.

Jika nama produk telah disediakan, sebuah instans baru ProductsRow dibuat menggunakan metode ProductsDataTable s NewProductsRow. Properti ProductsRow dari instans ProductName baru ini diatur ke TextBox nama produk saat ini, sementara properti SupplierID dan CategoryID ditetapkan ke properti SelectedValue dari DropDownLists di header antarmuka penyisipan. Jika pengguna memasukkan nilai untuk harga produk, nilai tersebut ditetapkan ke properti ProductsRow dari instans UnitPrice. Jika tidak, properti tersebut dibiarkan tidak ditetapkan, yang akan menghasilkan nilai NULL untuk UnitPrice dalam database. Akhirnya, properti Discontinued dan UnitsOnOrder masing-masing ditetapkan ke nilai False dan 0 yang sudah ditetapkan secara tetap.

Setelah properti ditetapkan ke ProductsRow instans, instans tersebut ditambahkan ke ProductsDataTable.

Setelah pengulangan For selesai, kami memeriksa apakah ada produk yang telah ditambahkan. Pengguna mungkin, pada akhirnya, mengklik Tambahkan Produk dari Pengiriman sebelum memasukkan nama produk atau harga apa pun. Jika setidaknya ada satu produk dalam ProductsDataTable, metode kelas ProductsBLL sUpdateWithTransaction dipanggil. Selanjutnya, data di-rebound ke ProductsGrid GridView sehingga produk yang baru ditambahkan akan muncul di antarmuka tampilan. StatusLabel diperbarui untuk menampilkan pesan konfirmasi dan ReturnToDisplayInterface dipanggil, menyembunyikan antarmuka penyisipan dan menampilkan antarmuka tampilan.

Jika tidak ada produk yang dimasukkan, antarmuka penyisipan tetap ditampilkan tetapi pesan Tidak ada produk yang ditambahkan. Masukkan nama produk dan harga satuan di kotak teks ditampilkan.

Gambar 13, 14, dan 15 menunjukkan antarmuka penyisipan dan tampilan saat digunakan. Pada Gambar 13, pengguna telah memasukkan nilai harga satuan tanpa nama produk yang sesuai. Gambar 14 menunjukkan antarmuka tampilan setelah tiga produk baru berhasil ditambahkan, sementara Gambar 15 menunjukkan dua produk yang baru ditambahkan di GridView (yang ketiga ada di halaman sebelumnya).

Nama Produk Diperlukan Saat Memasukkan Harga Satuan

Gambar 13: Nama Produk Diperlukan Saat Memasukkan Harga Satuan (Klik untuk melihat gambar ukuran penuh)

Tiga Sayuran Baru Telah Ditambahkan untuk Pemasok Mayumi

Gambar 14: Tiga sayuran baru telah ditambahkan untuk pemasok Mayumi (Klik untuk melihat gambar ukuran penuh)

Produk Baru Dapat Ditemukan di Halaman Terakhir GridView

Gambar 15: Produk Baru Dapat Ditemukan di Halaman Terakhir Dari GridView (Klik untuk melihat gambar ukuran penuh)

Nota

Logika penyisipan batch yang digunakan dalam tutorial ini mengemas penyisipan ke dalam lingkup transaksi. Untuk memverifikasi ini, dengan sengaja mengintroduksi kesalahan pada tingkat basis data. Alih-alih menetapkan properti instans ProductsRow baru CategoryID ke nilai yang dipilih di Categories DropDownList, tetapkan ke nilai yang mirip dengan i * 5. Berikut i adalah pengindeks perulangan dan memiliki nilai mulai dari 1 hingga 5. Oleh karena itu, ketika menambahkan dua produk atau lebih dalam sisipan batch, produk pertama akan memiliki nilai yang valid CategoryID (5), tetapi produk berikutnya akan memiliki CategoryID nilai yang tidak cocok dengan CategoryID nilai dalam Categories tabel. Efek keseluruhannya adalah bahwa sementara yang pertama INSERT akan berhasil, yang berikutnya akan gagal dengan pelanggaran batasan kunci asing. Karena sisipan batch adalah atomik, yang pertama INSERT akan digulung balik, mengembalikan database ke statusnya sebelum proses penyisipan batch dimulai.

Ringkasan

Selama ini dan dua tutorial sebelumnya, kami telah membuat antarmuka yang memungkinkan untuk memperbarui, menghapus, dan menyisipkan kumpulan data, yang semuanya menggunakan dukungan transaksi yang kami tambahkan ke Lapisan Akses Data dalam Membungkus Modifikasi Basis Data dalam Sebuah Transaksi tutorial. Untuk skenario tertentu, antarmuka pengguna pemrosesan batch tersebut sangat meningkatkan efisiensi pengguna akhir dengan mengurangi jumlah klik, postback, dan sakelar konteks keyboard-ke-mouse, sambil juga mempertahankan integritas data yang mendasarinya.

Tutorial ini melengkapi tampilan kami dalam bekerja dengan data batch. Set tutorial berikutnya mengeksplorasi berbagai skenario Lapisan Akses Data tingkat lanjut, termasuk menggunakan prosedur tersimpan dalam metode TableAdapter s, mengonfigurasi pengaturan tingkat koneksi dan perintah di DAL, mengenkripsi string koneksi, dan banyak lagi!

Selamat Pemrograman!

Tentang Penulis

Scott Mitchell, penulis tujuh buku ASP/ASP.NET dan pendiri 4GuysFromRolla.com, telah bekerja sama dengan teknologi Microsoft Web sejak 1998. Scott bekerja sebagai konsultan, pelatih, dan penulis independen. Buku terbarunya adalah Sams Teach Yourself ASP.NET 2.0 dalam 24 Jam. Dia dapat dijangkau di mitchell@4GuysFromRolla.com.

Ucapan terima kasih khusus kepada

Seri tutorial ini ditinjau oleh banyak peninjau yang bermanfaat. Peninjau utama untuk tutorial ini adalah Hilton Giesenow dan S ren Jacob Lauritsen. Tertarik untuk meninjau artikel MSDN saya yang akan datang? Jika demikian, hubungi saya di mitchell@4GuysFromRolla.com.