Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
oleh Scott Mitchell
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.
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.
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 ID
ProductsGrid
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.
Gambar 3: Menampilkan data yang dikembalikan dari metode kelas ProductsBLL
GetProducts
(Klik untuk melihat gambar ukuran penuh)
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.
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.
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.
Gambar 7: Konfigurasikan ObjectDataSource untuk Menggunakan Metode dari Kelas SuppliersBLL
GetSuppliers
(Klik untuk melihat gambar ukuran penuh)
Suppliers
Minta DropDownList menampilkan CompanyName
bidang data dan gunakan SupplierID
bidang data sebagai ListItem
nilainya.
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.
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
, ProductName2
UnitPrice2
, 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.
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.
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.
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).
Gambar 13: Nama Produk Diperlukan Saat Memasukkan Harga Satuan (Klik untuk melihat gambar ukuran penuh)
Gambar 14: Tiga sayuran baru telah ditambahkan untuk pemasok Mayumi (Klik untuk melihat gambar ukuran penuh)
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.