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 membungkus beberapa operasi Sisipkan dalam transaksi untuk memastikan bahwa semua penyisipan berhasil atau semua penyisipan digulung balik.
Pendahuluan
Dalam tutorial Pembaruan Batch , kami melihat penyesuaian kontrol GridView untuk menyajikan antarmuka tempat 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, bidang ProductName
dan UnitPrice
datanya diberi nilai yang dimasukkan di Kotak Teks, sementara nilai CategoryID
dan SupplierID
ditetapkan dari DropDownLists di bagian atas formulir. Nilai Discontinued
dan UnitsOnOrder
diatur ke nilai tetap false
dan 0 secara berturut-turut.
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 membungkus penyisipan dalam cakupan transaksi untuk memastikan atomitas. 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
diatur 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 Tombol ke ID
ProcessShipment
dan propertinya Text
ke Proses Pengiriman Produk. Atur properti GridView ke ID
ProductsGrid
dan, dari tag pintarnya, ikat ke ObjectDataSource baru bernama ProductsDataSource
. Konfigurasikan ObjectDataSource untuk menarik datanya dari ProductsBLL
metode kelas.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 ProductsBLL
Kelas 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 ProductName
, CategoryName
, SupplierName
, UnitPrice
, dan Discontinued
bidang. 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 untuk menyertakan dukungan penomoran dan pengurutan dengan mencentang kotak centang Aktifkan Halaman dan Aktifkan Pengurutan di 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 membahas cara mengubah properti panel secara programatik sebagai respons terhadap klik tombol untuk menampilkan satu antarmuka sambil menyembunyikan 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 Produk dan Menawarkan Kemampuan Sortir dan Halaman (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, dan menempatkannya di bawah Panel DisplayInterface
yang sudah 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. Bersihkan juga nilai properti Height
dan Width
pada Panel.
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 <table>
elemen melalui Perancang, Perancang tampaknya terlalu bersedia untuk menyuntikkan pengaturan style
tanpa 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.
Masukkan markup berikut di dalam tag <asp:Panel>
di InsertingInterface
Panel.
<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 di mana DropDownList pemasok dan kategori akan ditempatkan; BatchInsertFooterRow
untuk baris footer di mana Tombol Tambahkan Produk dari Pengiriman dan Batalkan akan berada; dan nilai bergantian BatchInsertRow
dan BatchInsertAlternatingRow
untuk baris-baris yang akan berisi kontrol TextBox untuk produk dan harga satuan. 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 Perancang, seperti diilustrasikan pada Gambar 6.
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 masing-masing sel yang sesuai dalam tabel, satu guna pemasok dan satu guna 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 atur daftar drop-down tab UPDATE ke (Tidak Ada). Klik Selesai untuk menyelesaikan wizard.
Gambar 7: Konfigurasikan ObjectDataSource untuk Menggunakan Metode SuppliersBLL
Kelas GetSuppliers
(Klik untuk melihat gambar 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 CategoriesDataSource
ObjectDataSource untuk menggunakan metode CategoriesBLL
kelas GetCategories
; sesuaikan daftar drop-down di tab PERBARUI dan HAPUS ke (Tidak Ada) dan klik Selesai untuk menuntaskan 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 Perancang untuk masing-masing 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, mengatur properti ControlToValidate
ke nilai yang sesuai ID
. Juga atur 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 RequiredFieldValidator apa pun, meskipun ProductName
bidang dalam Products
tabel database tidak mengizinkan NULL
nilai. 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 propertinya ShowMessageBox
ke true
dan atur propertinya 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 data, lalu atur properti Tombol ID
ke AddProducts
dan properti CancelButton
dan Text
masing-masing ke Tambahkan Produk dari Pengiriman dan Batalkan. Selain itu, atur CancelButton
properti kontrol ke CausesValidation
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 properti EnableViewState
ke false
memungkinkan kita untuk secara terprogram mengubah nilai-nilai properti Label dan mengembalikannya secara otomatis 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, atur StatusLabel
kontrol CssClass
properti ke Peringatan, yang merupakan nama kelas CSS yang ditentukan dalam Styles.css
yang menampilkan teks dalam font besar, miring, tebal, 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 DisplayInterface
Panel Visible
diatur ke true
(nilai default), sementara properti InsertingInterface
Panel Visible
diatur ke false
. 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 pengendali peristiwa untuk peristiwa Button Click
ini yang berisi kode berikut:
protected void ProcessShipment_Click(object sender, EventArgs e)
{
DisplayInterface.Visible = false;
InsertingInterface.Visible = true;
}
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 void AddProducts_Click(object sender, EventArgs e)
{
// TODO: Save the products
// Revert to the display interface
ReturnToDisplayInterface();
}
protected void CancelButton_Click(object sender, EventArgs e)
{
// Revert to the display interface
ReturnToDisplayInterface();
}
const int firstControlID = 1;
const int lastControlID = 5;
private void ReturnToDisplayInterface()
{
// Reset the control values in the inserting interface
Suppliers.SelectedIndex = 0;
Categories.SelectedIndex = 0;
for (int i = firstControlID; i <= lastControlID; i++)
{
((TextBox)InsertingInterface.FindControl("ProductName" + i.ToString())).Text =
string.Empty;
((TextBox)InsertingInterface.FindControl("UnitPrice" + i.ToString())).Text =
string.Empty;
}
DisplayInterface.Visible = true;
InsertingInterface.Visible = false;
}
Kedua Click
penangan acara hanya memanggil metode ReturnToDisplayInterface
, meskipun kita akan kembali ke penangan acara Tambahkan Produk dari Pengiriman Click
di Langkah 4 dan menambahkan kode untuk menyimpan produk-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 TextBoxes nama produk dan harga satuan di antarmuka penyisipan, dan digunakan dalam batas for
perulangan yang mengatur properti Text
dari kontrol TextBox agar 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 kolom 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 melakukan panggilan ke metode kelas ProductsBLL
s UpdateWithTransaction
dengan mengoperkan ProductsDataTable
. Ingat bahwa metode UpdateWithTransaction
, yang dibuat sebelumnya dalam tutorial Pembungkusan Modifikasi Database dalam Transaksi, meneruskan ProductsDataTable
ke ProductsTableAdapter
metode s UpdateWithTransaction
. Dari sana, transaksi ADO.NET dimulai, dan TableAdapter mengeluarkan pernyataan INSERT
ke database untuk setiap ProductsRow
yang ditambahkan dalam DataTable. Dengan asumsi semua produk ditambahkan tanpa kesalahan, transaksi dilakukan, jika tidak, itu digulung balik.
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, kita perlu memperingatkan pengguna dan tidak melanjutkan dengan penyisipan jika kondisi seperti itu terungkap. Kode penanganan aktivitas lengkap Click
mengikuti:
protected void AddProducts_Click(object sender, EventArgs e)
{
// Make sure that the UnitPrice CompareValidators report valid data...
if (!Page.IsValid)
return;
// Add new ProductsRows to a ProductsDataTable...
Northwind.ProductsDataTable products = new Northwind.ProductsDataTable();
for (int i = firstControlID; i <= lastControlID; i++)
{
// Read in the values for the product name and unit price
string productName = ((TextBox)InsertingInterface.FindControl
("ProductName" + i.ToString())).Text.Trim();
string unitPrice = ((TextBox)InsertingInterface.FindControl
("UnitPrice" + i.ToString())).Text.Trim();
// Ensure that if unitPrice has a value, so does productName
if (unitPrice.Length > 0 && productName.Length == 0)
{
// 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;
return;
}
// Only add the product if a product name value is provided
if (productName.Length > 0)
{
// Add a new ProductsRow to the ProductsDataTable
Northwind.ProductsRow newProduct = 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)
newProduct.UnitPrice = Convert.ToDecimal(unitPrice);
// Add any "default" values
newProduct.Discontinued = false;
newProduct.UnitsOnOrder = 0;
products.AddProductsRow(newProduct);
}
}
// If we reach here, see if there were any products added
if (products.Count > 0)
{
// Add the new products to the database using a transaction
ProductsBLL productsAPI = 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;
}
}
Penanganan aktivitas dimulai dengan memastikan bahwa Page.IsValid
properti mengembalikan nilai true
. Jika mengembalikan false
, maka itu berarti satu atau beberapa CompareValidator melaporkan data yang tidak valid; dalam kasus seperti itu kami tidak ingin mencoba memasukkan produk yang dimasukkan, karena hal tersebut akan menyebabkan pengecualian ketika mencoba menetapkan nilai harga unit yang dimasukkan pengguna ke properti ProductsRow
UnitPrice
.
Selanjutnya, instans baru ProductsDataTable
dibuat (products
). Perulangan for
digunakan untuk melakukan iterasi melalui TextBoxes nama produk dan harga satuan, sementara atribut 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 penanganan acara dihentikan.
Jika nama produk telah disediakan, instans baru ProductsRow
dibuat dengan menggunakan metode ProductsDataTable
s NewProductsRow
. Properti baru instance ProductsRow
ini diatur ke TextBox nama produk saat ini, sementara properti ProductName
dan SupplierID
ditetapkan ke properti CategoryID
dari DropDownLists di header antarmuka penyisipan. Jika pengguna memasukkan nilai untuk harga produk, nilai tersebut ditetapkan ke properti milik instans ProductsRow
UnitPrice
; jika tidak demikian, properti akan dibiarkan tidak ditetapkan, yang akan menghasilkan nilai NULL
untuk UnitPrice
dalam database. Akhirnya, properti Discontinued
dan UnitsOnOrder
ditetapkan ke nilai yang dikodekan secara permanen false
dan 0 secara berturut-turut.
Setelah properti ditetapkan ke instans ProductsRow
, instans tersebut ditambahkan ke ProductsDataTable
.
Pada penyelesaian for
perulangan, kami memeriksa apakah ada produk yang telah ditambahkan. Pengguna dapat, bagaimanapun juga, telah mengklik opsi Tambahkan Produk dari Pengiriman sebelum memasukkan nama atau harga produk apa pun. Jika setidaknya ada satu produk dalam ProductsDataTable
, metode kelas ProductsBLL
UpdateWithTransaction
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, sehingga 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 sedang beraksi. 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 dalam cakupan transaksi. Untuk memverifikasi ini, sengaja memasukkan kesalahan pada tingkat database. Misalnya, daripada menetapkan properti instans ProductsRow
baru CategoryID
ke nilai yang dipilih di Categories
DropDownList, tetapkan ke nilai seperti 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. Dampak akhirnya adalah bahwa meskipun yang pertama INSERT
akan berhasil, yang berikutnya akan gagal dengan pelanggaran batasan foreign key. Karena sisipan batch bersifat atomik, yang pertama INSERT
akan dibatalkan, mengembalikan database ke keadaannya sebelum proses penyisipan batch dimulai.
Ringkasan
Selama ini dan dua tutorial sebelumnya, kami telah membuat antarmuka yang memungkinkan untuk memperbarui, menghapus, dan menyisipkan batch data, yang semuanya menggunakan dukungan transaksi yang kami tambahkan ke Lapisan Akses Data dalam tutorial Membungkus Modifikasi Database dalam Transaksi. 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.