Tài liệu Bài giảng Lập trình cơ sở dữ liệu nâng cao với ado.net: Phần 3: Lập trình Cơ sở dữ liệu nâng cao với ADO.NET 
DANH SÁCH CÁC CHƯƠNG 
Chương 14: Điều khiển Giao dịch nâng cao 
Chương 15: Giới thiệu những ứng dụng Web -ASP.NET 
Chương 16: Sử dụng hỗ trợ XML của SQL Server 
Chương 17: Những dịch vụ Mạng 
Chương 14: Điều khiển Giao dịch nâng cao 
Tổng quan 
Trong Chương 3, "Giới thiệu về ngôn ngữ truy vấn có cấu trúc, " Bạn đã thấy là bạn có thể nhóm những câu lệnh 
SQL vào trong những giao dịch như thế nào. Những câu lệnh SQL này được coi như một đơn vị công việc lôgíc. 
Một ví dụ của điều này là một chuyển đổi tiền từ tài khoản này sang tài khoản khác sử dụng hai phát biểu 
UPDATE. Một rút tiền ra khỏi một tài khoản, và một chuyển tiền vào trong một tài khoản khác . Cả hai phát 
biểu UPDATE có thể được xem như là một giao dịch đơn vì cả hai phát biểu đều phải được giao phó hay phục 
nguyên cùng nhau, nếu không tiền có thể bị mất. 
Những cơ sở dữ liệu hiện đại có thể xử lý nhiều người sử dụng và những chương trình truy cập cơ sở d...
                
              
                                            
                                
            
 
            
                 124 trang
124 trang | 
Chia sẻ: hunglv | Lượt xem: 2004 | Lượt tải: 0 
              
            Bạn đang xem trước 20 trang mẫu tài liệu Bài giảng Lập trình cơ sở dữ liệu nâng cao với ado.net, để tải tài liệu gốc về máy bạn click vào nút DOWNLOAD ở trên
Phần 3: Lập trình Cơ sở dữ liệu nâng cao với ADO.NET 
DANH SÁCH CÁC CHƯƠNG 
Chương 14: Điều khiển Giao dịch nâng cao 
Chương 15: Giới thiệu những ứng dụng Web -ASP.NET 
Chương 16: Sử dụng hỗ trợ XML của SQL Server 
Chương 17: Những dịch vụ Mạng 
Chương 14: Điều khiển Giao dịch nâng cao 
Tổng quan 
Trong Chương 3, "Giới thiệu về ngôn ngữ truy vấn có cấu trúc, " Bạn đã thấy là bạn có thể nhóm những câu lệnh 
SQL vào trong những giao dịch như thế nào. Những câu lệnh SQL này được coi như một đơn vị công việc lôgíc. 
Một ví dụ của điều này là một chuyển đổi tiền từ tài khoản này sang tài khoản khác sử dụng hai phát biểu 
UPDATE. Một rút tiền ra khỏi một tài khoản, và một chuyển tiền vào trong một tài khoản khác . Cả hai phát 
biểu UPDATE có thể được xem như là một giao dịch đơn vì cả hai phát biểu đều phải được giao phó hay phục 
nguyên cùng nhau, nếu không tiền có thể bị mất. 
Những cơ sở dữ liệu hiện đại có thể xử lý nhiều người sử dụng và những chương trình truy cập cơ sở dữ liệu 
đồng thời, mỗi chương trình chạy tiềm tàng những giao dịch của mình trong cơ sở dữ liệu. Điều này được biết 
như những giao dịch trùng hợp bởi vì họ được chạy cùng lúc. Phần mềm cơ sở dữ liệu phải có khả năng để thỏa 
mãn những nhu cầu của tất cả những giao dịch trùng hợp này, cũng như bảo trì sự toàn vẹn của những hàng được 
cất giữ trong những bảng cơ sở dữ liệu. Bạn có thể kiểm soát lượng cô lập tồn tại giữa những giao dịch của bạn 
và những giao dịch khác mà có lẽ đang được chạy trong cơ sở dữ liệu. 
Trong Chương 8, "Thực hiện những lệnh Cơ sở dữ liệu, " Bạn đã thấy cách sử dụng một giao dịch với một đối 
tượng Lệnh như thế nào. Trong Chương 11, "Sử dụng những đối tượng Dataset để sửa đổi Dữ liệu, " Bạn đã thấy 
cách sử dụng một giao dịch với một DataAdapter như thế nào. Trong chương này, bạn sẽ đi sâu vào điều khiển 
giao dịch nâng cao sử dụng SQL Server và ADO.NET. 
Những mặt nổi bật trong Chương này: 
. Lớp SqlTransaction 
. Những thuộc tính giao dịch ACID 
. Sự Thiết đặt một savepoint 
. Đặt mức cô lập giao dịch 
. Hiểu về những khóa SQL Server 
LỚP SqlTransaction: 
Có ba lớp Giao dịch SqlTransaction, OleDbTransaction, và OdbcTransaction. Bạn sử dụng một đối tượng 
Transaction để đại diện cho một giao dịch cơ sở dữ liệu, và một đối tượng của lớp SqlTransaction để đại diện 
cho một giao dịch cơ sở dữ liệu trong một cơ sở dữ liệu SQL Server. Bảng 14.1 trình bày một số thuộc tính 
SqlTransaction, và Bảng 14.2 cho thấy một số những phương thức của SqlTransaction. Bạn sẽ xem xét cách sử 
dụng một số thuộc tính và phương pháp trong chương này. 
Bảng 14.1: những thuộc tính SqlTransaction 
Thuộc tính Kiểu dữ liệu Mô tả 
Connection SqlConnection Lấy kết nối cho giao dịch. 
IsolationLevel IsolationLevel Lấy mức cô lập cho giao dịch ( xem " thiết đặt mức cô lập Giao dịch")
Bảng 14.2: Những phương pháp SqlTransactiontransaction. 
Phương 
thức 
Kiểu 
trả về 
Mô tả 
Commit() void Thực hiện một giao phó để duy trì mẫu tin những câu lệnh SQL trong giao dịch. 
Rollback() void Bị quá tải. Thực hiện một sự hồi nguyên để huỷ bỏ những câu lệnh SQL trong giao dịch. 
Save() void Tạo ra một savepoint trong giao dịch mà có thể được dùng để huỷ bỏ một phần của giao 
dịch này. Chuỗi được chuyển cho phương pháp này chỉ rõ tên savepoint. Và rồi bạn có thể 
hồi nguyên giao dịch tới savepoint này ( xem " Sự thiết đặt một Savepoint "). 
THIẾT ĐẶT MỘT Savepoint 
Bạn có thể đặt một savepoint bất cứ nơi đâu bên trong một giao dịch. Điều này cho phép bạn hồi nguyên bất kỳ 
sự thay đổi nào được làm tới những hàng trong cơ sở dữ liệu sau lúc thiết đặt savepoint của bạn.Điều này có lẽ 
hữu ích nếu bạn có một giao dịch rất dài, bởi vì nếu bạn tạo ra một lỗi sau khi bạn thiết đặt một savepoint, Bạn 
không cần phải hồi nguyên suốt quá trình giao dịch tới khởi đầu. 
THIẾT ĐẶT MỘT Saverpoint SỬ DỤNG T-SQL 
Bạn đặt một savepoint trong T-SQL sử dụng phát biểu SAVE TRANSACTION (Giao dịch Lưu trữ), hay phiên 
bản tốc ký : SAVE TRANS. Cú pháp cho sự phát biểu này như sau: 
SAVE TRANS[ACTION] { savepointName | @savepointVariable } 
VỚI: 
savepointName chỉ rõ một chuỗi chứa tên bạn muốn gán tới savepoint của bạn. 
savepointVariable chỉ rõ một biến T- SQL chứa tên savepoint của bạn. Biến của bạn phải thuộc về kiểu dữ 
liệu char, varchar, nchar, hay nvarchar. 
Ví dụ sau đây thiết đặt một savepoint có tên SaveCustomer: 
SAVE TRANSACTION SaveCustomer 
Chúng ta hãy quan sát một script ví dụ T - SQL đầy đủ , nó đặt một savepoint bên trong một giao dịch. Danh 
sách 14.1 cho thấy một script T- SQL thực hiện những bước sau đây: 
1. Bắt đầu một giao dịch. 
2. Chèn một hàng vào trong bảng Customers với một CustomerID là J8COM. 
3. thiết đặt một savepoint . 
4. Chèn một hàng vào trong bảng Orders với một CustomerID là J8COM. 
5. Thực hiện một hồi nguyên tới savepoint, nó huỷ bỏ sự chèn thực hiện trong bước 4 trước đây, nhưng 
vẫn duy trì sự chèn thực hiện trong bước 2. 
6. Giao phó giao dịch, nó giao phó hàng được chèn vào trong bảng Customers trong bước 2. 
7. Lựa chọn hàng mới từ bảng Customers. 
8. Thử chọn hàng mà đã được hồi nguyên trong bước 5 từ bảng Customers. 
9. Xóa hàng mới từ bảng Customers. 
Danh sách 14.1: SAVEPOINT.SQL 
/* 
 Savepoint.sql illustrates how to use a savepoint 
*/ 
USE Northwind 
- step 1: begin the transaction 
BEGIN TRANSACTION 
- step 2: insert a row into the Customers table 
INSERT INTO Customers ( 
 CustomerID, CompanyName 
) VALUES ( 
 'J8COM', 'J8 Company' 
) 
- step 3: set a savepoint 
SAVE TRANSACTION SaveCustomer 
- step 4: insert a row into the Orders table 
INSERT INTO Orders ( 
 CustomerID 
) VALUES ( 
 'J8COM' 
); 
- step 5: rollback to the savepoint set in step 3 
ROLLBACK TRANSACTION SaveCustomer 
- step 6: commit the transaction 
COMMIT TRANSACTION 
- step 7: select the new row from the Customers table 
SELECT CustomerID, CompanyName 
FROM Customers 
WHERE CustomerID = 'J8COM' 
- step 8: attempt to select the row from the Orders table 
- that was rolled back in step 5 
SELECT OrderID, CustomerID 
FROM Orders 
WHERE CustomerID = 'J8COM' 
- step 9: delete the new row from the Customers table 
DELETE FROM Customers 
WHERE CustomerID = 'J8COM' 
Để chạy Script “ Savepoint.sql” sử dụng bộ phân tích truy vấn (Query Analyzer), bạn chọn File – Open , Mở 
script từ thư mục sql, và nhấn F5 trên bàn phím hay chọn Query – Execute từ thực đơn (menu). Hình 14.1 trình 
bày script “Savepoint.sql” đang chạy trong bộ phân tích truy vấn (Query Analyzer) 
Hình 14.1: chạy script “Savepoint.sql “ trong Query Analyzer 
Thiết đặt một Savepoint sử dụng một đối tượng SqlTransaction 
Bạn đặt một savepoint trong một đối tượng SqlTransaction bằng cách gọi phương thức Save() của nó, gởi một 
chuỗi chứa tên mà bạn muốn gán cho savepoint của bạn. Giả thiết bạn có một đối tượng SqlTransaction có tên 
mySqlTransaction; Ví dụ sau đây những thiết đặt một SaveCustomer có tên saveCustomer bằng cách gọi phương 
thức Save() của mySqlTransaction: 
mySqlTransaction.Save("SaveCustomer"); 
Và rồi Bạn có thể hồi nguyên bất kỳ sự thay đổi kế tiếp nào được thực hiện tới những hàng trong cơ sở dữ liệu 
bởi việc gọi phương thức Rollback() của mySqlTransaction, với việc chuyển tên savepoint tới phương thức 
Rollback(). Chẳng hạn: 
mySqlTransaction.Rollback("SaveCustomer"); 
Chúng ta hãy quan sát một chương trình C# đầy đủ ,nó đặt một savepoint bên trong một giao dịch. Danh sách 
14.2 cho thấy một chương trình thực hiện những bước sau đây: 
1. Tạo ra một đối tượng SqlTransaction có tên mySqlTransaction. 
2. Tạo ra một SqlCommand và gán thuộc tính Transaction (Giao dịch) của nó tới mySqlTransaction. 
3. Chèn một hàng vào trong bảng Customers. 
4. thiết đặt một savepoint bởi việc gọi phương thức Save() của mySqlTransaction, chuyển tên 
SaveCustomer tới phương thức Save() . 
5. Chèn một hàng vào trong bảng Orders. 
6. Thực hiện một hồi nguyên tới savepoint được thiết lập trong bước 4, nó huỷ bỏ sự chèn thực hiện trong 
bước 5 trước đây, nhưng vẫn duy trì sự chèn thực hiện trong bước 3. 
7. Hiển thị hàng mới được thêm vào bảng Customers. 
8. Xóa hàng mới từ bảng Customers 
9. Giao phó giao dịch. 
Danh sách 14.2: SAVEPOINT.CS 
/* 
 Savepoint.cs illustrates how to set a savepoint in a transaction 
*/ 
using System; 
using System.Data; 
using System.Data.SqlClient; 
class Savepoint 
{ 
 public static void Main() 
 { 
 SqlConnection mySqlConnection = 
 new SqlConnection( 
 "server=localhost;database=Northwind;uid=sa;pwd=sa" 
 ); 
 mySqlConnection.Open(); 
 // step 1: create a SqlTransaction object 
 SqlTransaction mySqlTransaction = 
 mySqlConnection.BeginTransaction(); 
 // step 2: create a SqlCommand and set its Transaction property 
 // to mySqlTransaction 
 SqlCommand mySqlCommand = 
 mySqlConnection.CreateCommand(); 
 mySqlCommand.Transaction = mySqlTransaction; 
 // step 3: insert a row into the Customers table 
 Console.WriteLine("Inserting a row into the Customers table "+ 
 "with a CustomerID of J8COM"); 
 mySqlCommand.CommandText = 
 "INSERT INTO Customers ( " + 
 " CustomerID, CompanyName " + 
 ") VALUES ( " + 
 " 'J8COM', 'J8 Company' "+ 
 ")"; 
 int numberOfRows = mySqlCommand.ExecuteNonQuery(); 
 Console.WriteLine("Number of rows inserted = "+ numberOfRows); 
 // step 4: set a savepoint by calling the Save() method of 
 // mySqlTransaction, passing the name "SaveCustomer" to 
 // the Save() method 
 mySqlTransaction.Save("SaveCustomer"); 
 // step 5: insert a row into the Orders table 
 Console.WriteLine("Inserting a row into the Orders table "+ 
 "with a CustomerID of J8COM"); 
 mySqlCommand.CommandText = 
 "INSERT INTO Orders ( " + 
 " CustomerID " + 
 ") VALUES ( " + 
 "'J8COM' "+ 
 ")"; 
numberOfRows = mySqlCommand.ExecuteNonQuery(); 
Console.WriteLine("Number of rows inserted = "+ numberOfRows); 
// step 6: rollback to the savepoint set in step 4 
Console.WriteLine("Performing a rollback to the savepoint"); 
mySqlTransaction.Rollback("SaveCustomer"); 
// step 7: display the new row added to the Customers table 
mySqlCommand.CommandText = 
 "SELECT CustomerID, CompanyName "+ 
 "FROM Customers "+ 
 "WHERE CustomerID = 'J8COM'"; 
 SqlDataReader mySqlDataReader = mySqlCommand.ExecuteReader(); 
 while (mySqlDataReader.Read()) 
 { 
 Console.WriteLine("mySqlDataReader[\" CustomerID\"] = "+ 
 mySqlDataReader["CustomerID"]); 
 Console.WriteLine("mySqlDataReader[\" CompanyName\"] = "+ 
 mySqlDataReader["CompanyName"]); 
 } 
 mySqlDataReader.Close(); 
 // step 8: delete the new row from the Customers table 
 Console.WriteLine("Deleting row with CustomerID of J8COM"); 
 mySqlCommand.CommandText = 
 "DELETE FROM Customers "+ 
 "WHERE CustomerID = 'J8COM'"; 
 numberOfRows = mySqlCommand.ExecuteNonQuery(); 
 Console.WriteLine("Number of rows deleted = "+ numberOfRows); 
 // step 9: commit the transaction 
 Console.WriteLine("Committing the transaction"); 
 mySqlTransaction.Commit(); 
 mySqlConnection.Close(); 
 } 
} 
Đầu ra từ chương trình này sau: 
Inserting a row into the Customers table with a CustomerID of J8COM 
Number of rows inserted = 1 
Inserting a row into the Orders table with a CustomerID of J8COM 
Number of rows inserted = 1 
Performing a rollback to the savepoint 
mySqlDataReader["CustomerID"] = J8COM 
mySqlDataReader["CompanyName"] = J8 Company 
Deleting row with CustomerID of J8COM 
Number of rows deleted = 1 
Committing the transaction 
Thiết đặt mức cô lập Giao dịch 
Mức cô lập giao dịch là hạn độ mà tới đó những sự thay đổi do một giao dịch tạo ra , được phân chia từ những 
giao dịch trùng hợp khác. Trước khi Tôi đi vào những chi tiết của nhiều mức cô lập giao dịch, bạn cần hiểu 
những kiểu sự cố mà có lẽ sẽ xuất hiện khi những giao dịch thường kỳ thử truy nhập vào cùng những hàng trong 
một bảng. Trong danh sách sau đây, Tôi sẽ sử dụng những ví dụ của hai giao dịch trùng hợp mà đang truy cập 
vào cùng những hàng để minh họa ba kiểu sự cố về xử lý giao dịch tiềm tàng. 
Phantoms(ma thuật): Transaction1 đọc một tập hợp của những hàng trả về bởi một mệnh đề WHERE được 
chỉ rõ. rồi Transaction 2 chèn vào một hàng mới, mà cũng xảy ra để đáp ứng mệnh đề WHERE của truy vấn 
sử dụng trước đó bởi Transaction 1. rồi Transaction1 đọc những hàng lần nữa sử dụng truy vấn giống như 
vậy, nhưng bây giờ lại thấy hàng vừa được chèn vào bởi Transaction 2. Hàng mới này được biết như một " 
ma thuật", bởi vì đối với Transaction 1, hàng này có vẻ như xuất hiện cách ma thuật. 
Nonrepeatable reads: Transaction1 đọc một hàng, và Transaction 2 cập nhật cùng hàng vừa được đọc bởi 
Transaction 1. Rồi Transaction 1 lại đọc cũng hàng đó lần nữa và phát hiện rằng hàng nó đọc trước đó bây 
giờ đã thay đổi. Điều này được biết như một " sự đọc không thể lặp lại ", bởi vì hàng trước đấy đọc bởi 
Transaction 1 đã được thay đổi. 
Dirty Reads (Sự đọc dơ): Transaction 1 cập nhật một hàng nhưng không giao phó sự cập nhật. Transaction 
2 đọc hàng được cập nhật. Rồi Transaction 1 thực hiện một hồi nguyên, huỷ bỏ sự cập nhật trước đây. Bây 
giờ hàng vừa được đọc bởi Transaction 2 không còn hợp lệ nữa ( hay nó "dơ ") vì sự cập nhật thực hiện bởi 
Transaction 1 không được giao phó khi hàng được đọc bởi Transaction 2. 
Để giải quyết những vấn đề tiềm tàng này, những cơ sở dữ liệu thực hiện nhiều mức cô lập giao dịch để cản trở 
những giao dịch trùng hợp can thiệp lẫn nhau. SQL tiêu chuẩn định nghĩa bốn mức cô lập, được trình bày trong 
Bảng 14.3. Những mức này được trình bày theo mức cô lập tăng dần. 
Bảng 14.3: những mức cô lập Tiêu chuẩn SQL 
Mức cô lập Mô tả 
READ 
UNCOMMITTED 
Ma thuật, những sự đọc không thể lặp lại, và những sự đọc dơ được cho phép. 
READ COMMITTED Ma thuật và sự đọc không không thể lặp lại được cho phép, nhưng những sự đọc dơ thì 
Không. Đây là mặc định cho SQL Server. 
REPEATABLE READ Ma thuật được cho phép, nhưng những sự đọc dơ và không thể lập lại thì không. 
SERIALIZABLE Ma thuật, những sự đọc không không thể lặp lại, và những sự đọc dơ không được cho 
phép. Đây là mặc định cho SQL tiêu chuẩn. 
SQL Server hỗ trợ tất cả những mức cô lập giao dịch này. Mức cô lập giao dịch mặc định được định nghĩa bởi 
SQL tiêu chuẩn được xếp theo thứ tự, ngoại trừ mặc định sử dụng bởi SQL Server là READ COMMITTED (sự 
đọc được giao phó), nó được chấp nhận cho hầu hết những ứng dụng. 
Cảnh báo: khi bạn đặt mức cô lập giao dịch là SERIALIZABLE (xếp theo thứ tự), bất kỳ hàng nào bạn truy 
cập bên trong một giao dịch kế tiếp sẽ được " khóa ", có nghĩa rằng không có giao dịch nào khác có 
thể sửa đổi những hàng này. Thậm chí những hàng bạn truy xuất sử dụng một phát biểu SELECT 
cũng sẽ bị khóa. Bạn phải giao phó hay hồi nguyên giao dịch để bỏ những khóa và cho phép những 
giao dịch khác truy cập những hàng này . Bạn sử dụng SERIALIZABLE (xếp theo thứ tự) chỉ khi bạn 
phải bảo đảm rằng giao dịch của bạn được cô lập từ những giao dịch khác. Bạn sẽ học nhiều hơn về 
điều này sau trong mục " Tìm hiểu những sự khóa SQL Server." 
Ngoài ra, ADO.NET còn hỗ trợ một số mức cô lập giao dịch, được định nghĩa trong liệt kê 
System.Data.IsolationLevel. Bảng 14.4 cho thấy những thành viên của liệt kê này. 
Bảng 14.4: những thành viên liệt kê IsolationLevel 
Mức cô lập Mô tả 
Chaos Những sự thay đổi đang xem xét từ nhiều giao dịch được cô lập không thể bị ghi đè lên. SQL 
Server không hỗ trợ mức cô lập này. 
ReadCommitted Những" ma thuật" và "sự đọc không đáng được lặp lại " được cho phép, nhưng những sự 
đọc bẩn thỉu thì không. Đây là mặc định. 
ReadUncommitted Ma thuật, những sự đọc không đáng được lặp lại, và những sự đọc dơ được cho phép. 
RepeatableRead Ma thuật được cho phép, nhưng những sự đọc bẩn và không đáng được lặp lại thì không . 
Serializable Ma thuật, những sự đọc không đáng được lặp lại, và những sự đọc bẩn không được cho phép.
Unspecified Một mức cô lập khác so với cái chỉ định hiện đang dùng, nhưng mức độ không thể xác định 
được . SQL Server không hỗ trợ mức cô lập này. 
Thiết đặt giao dịch sử dụng T- SQL 
Cũng như việc học thiết đặt mức cô lập giao dịch sử dụng T- SQL, Bạn sẽ thấy một ví dụ trình bày hiệu ứng của 
việc thiết đặt những mức cô lập giao dịch khác nhau trong SQL Server- sử dụng công cụ phân tích truy vấn 
(Query Analyzer tool). 
Để thiết đặt mức cô lập giao dịch trong T- SQL, Bạn sử dụng lệnh SET TRANSACTION ISOLATION LEVEL. 
Cú pháp cho lệnh này như sau: 
SET TRANSACTION ISOLATION LEVEL { 
 READ COMMITTED | 
 READ UNCOMMITTED | 
 REPEATABLE READ | 
 SERIALIZABLE 
 } 
Như bạn có thể thấy từ cú pháp trước đây, bạn có thể đặt cô lập giao dịch tới bất kỳ những mức nào chỉ ra trước 
đó trong Bảng 14.3. 
Ví dụ sau đây đặt mức cô lập giao dịch tới SERIALIZABLE: 
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE 
Ghi chú 
Mức cô lập giao dịch được gán cho phiên họp của các bạn. Bởi vậy, nếu bạn thực hiện nhiều giao dịch trong 
một phiên họp, tất cả những giao dịch của bạn sẽ sử dụng cùng mức như vậy. Nếu bạn muốn thay đổi mức 
trong phiên họp của bạn, bạn đơn giản thực hiện lệnh SET TRANSACTION ISOLATION LEVEL với mức 
mới của bạn. Tất cả các giao dịch kế tiếp trong phiên họp của bạn sẽ sử dụng mức mới. 
Ví dụ sau đây đặt mức cô lập giao dịch tới READ COMMITTED: 
SET TRANSACTION ISOLATION LEVEL READ COMMITTED 
Chúng ta hãy quan sát một ví dụ đầy đủ mà thiết đặt mức cô lập giao dịch sử dụng T- SQL. Danh sách 14.3 cho 
thấy một ví dụ sử dụng Script T- SQL để đặt mức cô lập giao dịch đầu tiên tới SERIALIZABLE (xếp theo thứ tự) 
và thực hiện một giao dịch, và sau đó thiết đặt mức tới READ COMMITTED và thực hiện giao dịch khác. 
Danh sách 14.3: TransactionIsolation.sql 
/* 
 TransactionIsolation.sql illustrates how to set the 
 transaction isolation level 
*/ 
USE Northwind 
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE 
 BEGIN TRANSACTION 
 SELECT CustomerID, CompanyName 
 FROM Customers 
 WHERE CustomerID IN ('ALFKI', 'J8COM') 
 INSERT INTO Customers ( 
 CustomerID, CompanyName 
 ) VALUES ( 
 'J8COM', 'J8 Company' 
 ) 
 UPDATE Customers 
 SET CompanyName = 'Widgets Inc.' 
 WHERE CustomerID = 'ALFKI' 
 SELECT CustomerID, CompanyName 
 FROM Customers 
 WHERE CustomerID IN ('ALFKI', 'J8COM') 
 COMMIT TRANSACTION 
SET TRANSACTION ISOLATION LEVEL READ COMMITTED 
 BEGIN TRANSACTION 
 UPDATE Customers 
 SET CompanyName = 'Alfreds Futterkiste' 
 WHERE CustomerID = 'ALFKI' 
 DELETE FROM Customers 
 WHERE CustomerID = 'J8COM' 
 SELECT CustomerID, CompanyName 
 FROM Customers 
 WHERE CustomerID IN ('ALFKI', 'J8COM') 
 COMMIT TRANSACTION 
Hình 14.2 Trình bày script TransactionIsolation.sql đang chạy trong Query Analyzer. Trong ô vuông những kết 
quả ở một nửa phần dưới của Query Analyzer, hai tập hợp đầu tiên của những hàng được sinh ra bởi transaction 
đầu tiên, và một hàng đơn cuối cùng được phát sinh bởi transaction thứ hai. 
Hình 14.2: Sript TransactionIsolation.sql đang chạy trong Query Analyzer. 
Đặt mức cô lập giao dịch của một đối tượng SqlTransaction 
Cùng với việc đặt mức cô lập giao dịch của một đối tượng SqlTransaction, bạn sẽ thấy một ví dụ cho thấy hiệu 
ứng của những mức khác nhau được thiết đặt ở một chương trình C# . 
Bạn tạo ra một đối tượng SqlTransaction bởi sự gọi phương thức BeginTransaction() của đối tượng 
SqlConnection. Phương thức này bị quá tải như sau: 
SqlTransaction BeginTransaction() 
SqlTransaction BeginTransaction(IsolationLevel myIsolationLevel) 
SqlTransaction BeginTransaction(string transactionName) 
SqlTransaction BeginTransaction(IsolationLevel myIsolationLevel, string 
transactionName) 
VỚI: 
myIsolationLevel: chỉ rõ mức cô lập giao dịch của bạn. Đây là một hằng số từ liệt kê 
System.Data.IsolationLevel , cho những thành viên được chỉ định trước đó trong Bảng 14.4. 
transactionName chỉ rõ một chuỗi chứa tên bạn muốn gán tới giao dịch của các bạn. 
Trong những ví dụ trong mục này, giả thiết bạn có một SqlConnection mở có tên mySqlConnection mà được nối 
tới cơ sở dữ liệu Northwind SQL server. Ví dụ sau đây tạo ra một SqlTransaction có tên serializableTrans bởi sự 
gọi phương thức BeginTransaction() của mySqlConnection; chú ý IsolationLevel của Serializable được chuyển 
cho BeginTransaction(): 
SqlTransaction serializableTrans = 
 mySqlConnection.BeginTransaction(IsolationLevel.Serializable); 
Ví dụ kế tiếp tạo ra một SqlCommand có tên serializableCommand, và đặt thuộc tính Transaction của nó tới 
serializableTrans: 
SqlCommand serializableCommand = 
 mySqlConnection.CreateCommand(); 
serializableCommand.Transaction = serializableTrans; 
Bất kỳ câu lệnh SQL nào được thực hiện sử dụng serializableCommand bây giờ sẽ sử dụng serializableTrans, và 
bởi vậy sẽ được thực hiện trong một serializable transaction. Ví dụ sau thực hiện một phát biểu INSERT để 
thêm một hàng vào bảng Customers : 
serializableCommand.CommandText = 
 "INSERT INTO Customers ("+ 
 "CustomerID, CompanyName "+ 
 ") VALUES ("+ 
 "'J8COM', 'J8 Company' "+ 
 ")"; 
int numberOfRows = serializableCommand.ExecuteNonQuery(); 
Ví dụ kế tiếp thực hiện một phát biểu Cập nhật 
serializableCommand.CommandText = 
 "UPDATE Customers "+ 
 "SET CompanyName = 'Widgets Inc.' "+ 
 "WHERE CustomerID = 'ALFKI'"; 
numberOfRows = serializableCommand.ExecuteNonQuery(); 
Cuối cùng, ví dụ sau đây giao phó những phát biểu UPDATE và INSERT bởi sự gọi phương thức Commit() của 
erializableTrans: 
serializableTrans.Commit(); 
Danh sách 14.4 cho thấy một chương trình chứa những phương thức sau đây: 
DisplayRows() chọn và hiển thị bất kỳ hàng nào từ bảng Customers với một CustomerID là ALFKI hay 
J8COM. 
PerformSerializableTransaction() Thực hiện mã được trình bày trước đó trong mục này để tạo ra một đối 
tượng SqlTransaction với một mức cô lập là Serializable, và sử dụng nó để thực hiện một phát biểu INSERT 
và UPDATE. 
PerformReadCommittedTransaction() Tạo ra một đối tượng SqlTransaction với một mức cô lập là 
ReadCommitted, Và sử dụng nó để thực hiện những phát biểu Cập nhật và Xóa. 
Danh sách 14.4: TransactionIsolation.cs 
/* 
 TransactionIsolation.cs illustrates how to set the 
 transaction isolation level 
*/ 
using System; 
using System.Data; 
using System.Data.SqlClient; 
class TransactionIsolation 
{ 
 public static void DisplayRows( 
 SqlCommand mySqlCommand 
 ) 
 { 
 mySqlCommand.CommandText = 
 "SELECT CustomerID, CompanyName "+ 
 "FROM Customers "+ 
 "WHERE CustomerID IN ('ALFKI', 'J8COM')"; 
 SqlDataReader mySqlDataReader = mySqlCommand.ExecuteReader(); 
 while (mySqlDataReader.Read()) 
 { 
 Console.WriteLine("mySqlDataReader[\" CustomerID\"] = "+ 
 mySqlDataReader["CustomerID"]); 
 Console.WriteLine("mySqlDataReader[\" CompanyName\"] = "+ 
 mySqlDataReader["CompanyName"]); 
 } 
 mySqlDataReader.Close(); 
 } 
 public static void PerformSerializableTransaction( 
 SqlConnection mySqlConnection 
 ) 
 { 
 Console.WriteLine("\nIn PerformSerializableTransaction()"); 
 // create a SqlTransaction object and start the transaction 
 // by calling the BeginTransaction() method of the SqlConnection 
 // object, passing the IsolationLevel of Serializable to the method 
 SqlTransaction serializableTrans = 
 mySqlConnection.BeginTransaction(IsolationLevel.Serializable); 
 // create a SqlCommand and set its Transaction property 
 // to serializableTrans 
 SqlCommand serializableCommand = 
 mySqlConnection.CreateCommand(); 
 serializableCommand.Transaction = serializableTrans; 
 // call the DisplayRows() method to display rows from 
 // the Customers table 
 DisplayRows(serializableCommand); 
 // insert a new row into the Customers table 
 Console.WriteLine("Inserting new row into Customers table "+ 
 "with CustomerID of J8COM"); 
 serializableCommand.CommandText = 
 "INSERT INTO Customers ("+ 
 "CustomerID, CompanyName "+ 
 ") VALUES ("+ 
 "'J8COM', 'J8 Company' "+ 
 ")"; 
 int numberOfRows = serializableCommand.ExecuteNonQuery(); 
 Console.WriteLine("Number of rows inserted = "+ numberOfRows); 
 // update a row in the Customers table 
 Console.WriteLine("Setting CompanyName to 'Widgets Inc.' for "+ 
 "row with CustomerID of ALFKI"); 
 serializableCommand.CommandText = 
 "UPDATE Customers "+ 
 "SET CompanyName = 'Widgets Inc.' "+ 
 "WHERE CustomerID = 'ALFKI'"; 
 numberOfRows = serializableCommand.ExecuteNonQuery(); 
 Console.WriteLine("Number of rows updated = "+ numberOfRows); 
 DisplayRows(serializableCommand); 
 // commit the transaction 
 serializableTrans.Commit(); 
 } 
 public static void PerformReadCommittedTransaction( 
 SqlConnection mySqlConnection 
 ) 
 { 
 Console.WriteLine("\nIn PerformReadCommittedTransaction()"); 
 // create a SqlTransaction object and start the transaction 
 // by calling the BeginTransaction() method of the SqlConnection 
 // object, passing the IsolationLevel of ReadCommitted to the method 
 // (ReadCommitted is actually the default) 
 SqlTransaction readCommittedTrans = 
 mySqlConnection.BeginTransaction(IsolationLevel.ReadCommitted); 
 // create a SqlCommand and set its Transaction property 
 // to readCommittedTrans 
 SqlCommand readCommittedCommand = 
 mySqlConnection.CreateCommand(); 
 readCommittedCommand.Transaction = readCommittedTrans; 
 // update a row in the Customers table 
 Console.WriteLine("Setting CompanyName to 'Alfreds Futterkiste' "+ 
 "for row with CustomerID of ALFKI"); 
 readCommittedCommand.CommandText = 
 "UPDATE Customers "+ 
 "SET CompanyName = 'Alfreds Futterkiste' "+ 
 "WHERE CustomerID = 'ALFKI'"; 
 int numberOfRows = readCommittedCommand.ExecuteNonQuery(); 
 Console.WriteLine("Number of rows updated = "+ numberOfRows); 
 // delete the new row from the Customers table 
 Console.WriteLine("Deleting row with CustomerID of J8COM"); 
 readCommittedCommand.CommandText = 
 "DELETE FROM Customers "+ 
 "WHERE CustomerID = 'J8COM'"; 
 numberOfRows = readCommittedCommand.ExecuteNonQuery(); 
 Console.WriteLine("Number of rows deleted = "+ numberOfRows); 
 DisplayRows(readCommittedCommand); 
 // commit the transaction 
 readCommittedTrans.Commit(); 
 } 
 public static void Main() 
 { 
 SqlConnection mySqlConnection = 
 new SqlConnection( 
 "server=localhost;database=Northwind;uid=sa;pwd=sa" 
 ); 
 mySqlConnection.Open(); 
 PerformSerializableTransaction(mySqlConnection); 
 PerformReadCommittedTransaction(mySqlConnection); 
 mySqlConnection.Close(); 
 } 
} 
Đầu ra từ chương trình này như sau: 
In PerformSerializableTransaction() 
mySqlDataReader["CustomerID"] = ALFKI 
mySqlDataReader["CompanyName"] = Alfreds Futterkiste 
Inserting new row into Customers table with CustomerID of J8COM 
Number of rows inserted = 1 
Setting CompanyName to 'Widgets Inc.' for row with CustomerID of ALFKI 
Number of rows updated = 1 
mySqlDataReader["CustomerID"] = ALFKI 
mySqlDataReader["CompanyName"] = Widgets Inc. 
mySqlDataReader["CustomerID"] = J8COM 
mySqlDataReader["CompanyName"] = J8 Company 
In PerformReadCommittedTransaction() 
Setting CompanyName to 'Alfreds Futterkiste' for row with CustomerID of ALFKI 
Number of rows updated = 1 
Deleting row with CustomerID of J8COM 
Number of rows deleted = 1 
mySqlDataReader["CustomerID"] = ALFKI 
mySqlDataReader["CompanyName"] = Alfreds Futterkiste 
Tìm hiểu những sự khóa SQL server 
SQL Server sử dụng những sự khóa để thực hiện cô lập giao dịch và để bảo đảm thông tin được cất giữ chắc 
chắn trong một cơ sở dữ liệu .Những sự khóa ngăn ngừa một người sử dụng đọc hay thay đổi một hàng mà đang 
được thay đổi bởi một người sử dụng khác. Ví dụ, khi bạn cập nhật một hàng, một sự khóa hàng được đặt trên 
hàng đó ngăn ngừa người sử dụng khác cập nhật hàng đó cùng một thời điểm. 
Những kiểu khóa của SQL Server 
Máy chủ phục vụ SQL sử dụng nhiều kiểu khóa, Một số trong đó được trình bày trong Bảng 14.5. Bảng này trình 
bày những sự khóa trong thứ tự tăng dần của độ hạt khóa, nó tham chiếu tới kích thước của nguồn tài nguyên sẽ 
bị khóa. Chẳng hạn, một sự khóa hàng có một độ hạt tinh luyện hơn so với một sự khóa trang. 
Bảng 14.5: những kiểu khóa của máy chủ phục vụ SQL 
Kiểu khóa Mô tả 
Row (RID) Được đặt lên một hàng trong một bảng. Thay thế cho định danh hàng. Thường dùng để xác định 
một hàng duy nhất. 
Key (KEY) Được đặt lên một hàng bên trong một chỉ số. Dùng để bảo vệ những phạm vi của khóa trong 
serializable transactions. 
Page (PAG) Được đặt trên một trang, có chứa 8 KB hàng hay chỉ số dữ liệu. 
Extent 
(EXT) 
Được đặt trên một phạm vi, một nhóm kề nhau của 8 Dữ liệu hay những trang chỉ số 
Table (TAB) Đặt trên một bảng và khóa tất cả những hàng và những chỉ số trong bảng này. 
Database 
(DB) 
Dùng để khóa toàn bộ cơ sở dữ liệu khi người quản trị cơ sở dữ liệu đặt nó vào trong kiểu người 
sử dụng đơn cho sự bảo trì. 
Những kiểu khóa của máy chủ phục vụ SQL 
Máy chủ phục vụ SQL sử dụng những kiểu khóa khác nhau để xác định mức khóa đặt trên nguồn tài nguyên. 
Những kiểu khóa này được trình bày trong Bảng 14.6. Bạn sẽ thấy những kiểu khóa này trong mục kế tiếp. 
Bảng 14.6: những kiểu khóa của máy chủ phục vụ SQL 
Kiểu khóa Mô tả 
Shared (S) Chỉ định một giao dịch sẽ đọc từ nguồn tài nguyên sử dụng một phát biểu SELECT. Ngăn 
ngừa những giao dịch khác sửa đổi nguồn tài nguyên được khóa. Một sự khóa dùng chung 
được thả tự do ngay khi dữ liệu được đọc- trừ phi mức cô lập giao dịch được đặt tới 
REPEATABLE READ hay SERIALIZABLE. 
Update (U) Chỉ rõ một giao dịch định sửa đổi một nguồn tài nguyên sử dụng một phát biểu INSERT, 
UPDATE, hay DELETE. Sự khóa phải được tăng tới một sự khóa dành riêng trước khi giao 
dịch thật sự thực hiện sự sửa đổi. 
Exclusive (X) Cho phép giao dịch sửa đổi nguồn tài nguyên sử dụng một phát biểu INSERT, UPDATE, hay 
DELETE . Không có giao dịch nào khác có thể đọc từ hay viết tới một nguồn tài nguyên mà 
trên đó một sự khóa dảnh riêng đã được đặt. 
Intent shared (IS) Chỉ rõ là giao dịch định đặt một khóa dùng chung trên một số nguồn tài nguyên tới một mức 
độ tốt hơn bên trong tài nguyên đó. Chẳng hạn, sự đặt một khóa IS trên một bảng chỉ báo rằng 
giao dịch định đặt một khóa dùng chung trên một số những trang hay những hàng bên trong 
bảng này. Không có giao dịch nào khác có thể đặt một khóa riêng trên một nguồn tài nguyên 
mà đã có một khóa IS trên nó. 
Intent exclusive 
(IX) 
Chỉ báo rằng giao dịch định đặt một khóa riêng trên một nguồn tài nguyên với một mức độ 
hạt tốt hơn. Không có giao dịch nào khác có thể đặt một khóa riêng trên một nguồn tài 
nguyên mà đã có một khóa IX trên nó. 
Shared with 
intent exclusive 
(SIX) 
Chỉ báo rằng giao dịch định đọc tất cả những nguồn tài nguyên có một lượng độ hạt tốt hơn 
và sửa đổi một số tài nguyên đó. Chẳng hạn, việc đặt một khóa SIX trên một bảng cho biết 
giao dịch định đọc tất cả những hàng trong bảng này và sửa đổi một số trong những hàng đó. 
Không có giao dịch nào khác có thể đặt một khóa riêng trên một nguồn tài nguyên mà đã có 
một khóa SIX trên nó. 
Schema 
modification 
(Sch-M) 
Chỉ báo rằng một phát biểu ngôn ngữ định nghĩa dữ liệu (Data Definition Language _DDL) 
sẽ được thực hiện trên một nguồn tài nguyên mô hình, chẳng hạn, DROP TABLE. Không có 
giao dịch nào khác có thể đặt một sự khóa trên một tài nguyên mà đã có một khóa Sch- M 
trên nó. 
Schema stability 
(Sch-S) 
Chỉ báo rằng một câu lệnh SQL mà sử dụng nguồn tài nguyên, sắp sửa được thực hiện, như 
một phát biểu SELECT chẳng hạn. Những giao dịch khác có thể đặt một khóa trên một tài 
nguyên mà đã có một khóa Sch- S trên nó; chỉ một sự khóa cải biến mô hình bị ngăn cản. 
Bulk update (BU) Chỉ báo rằng một thao tác sao chép khối lượng lớn để tải những hàng vào trong một bảng sẽ 
được thực hiện. Một khóa cập nhật khối lượng lớn cho phép những quá trình khác tới khối dữ 
liệu _sao chép dữ liệu đồng thời vào trong cùng một bảng , nhưng cản trở những quá trình 
khác mà không phải là dữ liệu sao chép khối lớn truy nhập vào bảng. Để thêm thông tin về dữ 
liệu sao chép khối lớn tới một bảng, xem những sách tài liệu trực tuyến Máy chủ phục vụ 
SQL. 
Xem thông tin về khóa máy chủ phục vụ SQL 
Bạn có thể xem thông tin về khóa trong một cơ sở dữ liệu sử dụng SQL Server Enterprise Manager. Bạn mở thư 
mục Management, mở nút Current Activity (hoạt động hiện thời), rồi mở nút Locks/Process ID hoặc những nút 
Locks/Object . nút Locks/Process ID cho bạn thấy những khóa được đặt bởi mỗi Quá trình; mỗi quá trình có một 
số SPID mà được gán bởi SQL Server để xác định quá trình. nút Locks/Object cho bạn thấy những khóa được 
đặt trên mỗi nguồn tài nguyên bởi tất cả các quá trình. 
Mẹo nhỏ: Bạn cũng có thể cũng xem thông tin về khóa bởi việc thực thi thủ tục lưu trữ sp_lock , mặc dù 
Enterprise Manager tổ chức thông tin trong một định dạng dễ đọc hơn. 
Giả thiết bạn đã bắt đầu giao dịch sau (thí dụ, sử dụng Query Analyzer) với những câu lệnh T - SQL sau đây: 
USE Northwind 
BEGIN TRANSACTION 
UPDATE Customers 
SET CompanyName = 'Widgets Inc.' 
WHERE CustomerID = 'ALFKI' 
Việc này đặt một khóa dùng chung trên cơ sở dữ liệu Northwind và một số khóa trên bảng Customers, mà bạn có 
thể xem- sử dụng Enterprise Manager . Hình 14.3 cho thấy rằng những sự khóa này sử dụng những nút Locks/ 
Process ID của Enterprise Manager. SPID = 51 tương ứng với Query Analyzer nơi tôi đã chạy những câu lệnh T-
SQLT trước đây. Như bạn có thể thấy từ hình này, một số khóa được đặt bởi những câu lệnh T-SQL trước . 
 Hình 14.3: việc xem những khóa sử dụng nút Locks/ Process ID của Enterprise Manager. 
Để hồi nguyên giao dịch trước đây, thực hiện câu lệnh T-SQL sau đây: 
ROLLBACK TRANSACTION 
Để thả tự do cho những khóa, thực hiện câu lệnh T- SQLsau đây: 
 COMMIT TRANSACTION 
Thông tin trong khung bên phải của Hình 14.3 trình bày những khóa, và thông tin này được chia vào trong 
những cột sau đây: 
Object Đối tượng sẽ bị khóa. 
Lock Type Kiểu khóa, tương ứng với một trong số những kiểu được chỉ ra trước đó trong Bảng 14.5. 
Mode chế độ khóa, tương ứng tới một trong số những chế độ khóa được chỉ ra trước đó trong Bảng 14.6. 
Tatus Tình trạng khóa, là GRANT (khóa đã được cấp phát thành công ), CNVT (khóa đã được chuyển 
đổi), hay WAIT(đợi khóa). 
Owner kiểu khóa chủ sở hữu, như Sess (khóa phiên ) hay Xact (khóa giao dịch). 
Index tên của chỉ số sẽ được khóa (nếu có). 
Resource từ định danh tài nguyên của đối tượng sẽ bị khóa (nếu có). 
Khóa Giao dịch 
Một giao dịch có thể ngăn giao dịch khác thu một khóa trên một tài nguyên. Chẳng hạn, chúng ta hãy cho là bạn 
bắt đầu một giao dịch sử dụng T -SQL sau, nó đồng nhất với T- SQL trong mục trước : 
USE Northwind 
BEGIN TRANSACTION 
 UPDATE Customers 
 SET CompanyName = 'Widgets Inc.' 
 WHERE CustomerID = 'ALFKI' 
Như bạn thấy trong mục trước đây, nó đặt một số khóa trên những đối tượng Customers. 
Nếu bạn thử cập nhật cùng một hàng - mà không kết thúc giao dịch trước - sử dụng những câu lệnh T-SQL sau 
đây: 
USE Northwind 
UPDATE Customers 
SET CompanyName = 'Alfreds Futterkiste' 
WHERE CustomerID = 'ALFKI' 
rồi Cập nhật này sẽ đợi cho đến khi giao dịch trước hòan tất việc giao phó hay hồi nguyên. Hình 14.4 cho thấy 
rằng hai giao dịch này được bắt đầu trong Query Analyzer. Giao dịch đầu tiên, được trình bày trong phần trên 
của Hình 14.4 , đang khóa giao dịch thứ hai trong phần dưới. 
 Hình 14.4: giao dịch trên phần trên đang khóa giao dịch trong phần dưới 
Để giao phó giao dịch trước và thả tự do cho những khóa cho giao dịch đầu tiên, bạn có thể thực hiện câu lệnh T- 
SQLsau đây: 
COMMIT TRANSACTION 
Điều này cho phép Cập nhật thứ hai (hiển thị ở phần dưới của Query Analyzer) lấy khóa thích hợp để Cập nhật 
hàng và tiến hành, như trình bày trong Hình 14.5 
 Hình 14.5: Một khi giao dịch ở phần trên đã được giao phó, sự Cập nhật ở phần dưới tiến hành. 
Gán Timeout cho khóa 
Theo mặc định, một câu lệnh SQL sẽ đợi đến vô tận để nhận một khóa. Bạn có thể thay đổi điều này bởi việc 
thực thi lệnh LOCK_TIMEOUT. Chẳng hạn, lệnh sau đây đặt khóa timeout tới 1 giây (1.000 mili-giây) 
SET LOCK_TIMEOUT 1000 
Nếu một câu lệnh SQL phải đợi lâu hơn 1 giây, máy chủ phục vụ SQL sẽ trả về một lỗi và hủy bỏ câu lệnh SQL. 
Bạn cũng có thể thực thi lệnh SET LOCK_TIMEOUT trong mã C#. Chẳng hạn: 
mySqlCommand.CommandText = "SET LOCK_TIMEOUT 1000"; 
mySqlCommand.ExecuteNonQuery(); 
Bạn sẽ thấy sự sử dụng lệnh SET LOCK_TIMEOUT trong mục kế tiếp. 
Blocking và Serializable/Repeatable Read Transactions 
Serializable và repeatable read transactions khóa những hàng mà chúng đang truy xuất, như thế những giao dịch 
khác không thể cập nhật những hàng đó. Serializable và repeatable read transactions làm điều này để những hàng 
không bị thay đổi sau khi chúng đọc. 
Ví dụ, nếu bạn chọn hàng từ bảng Customers với một CustomerID là ALFKI sử dụng một serializable 
transaction, rồi nỗ lực cập nhật hàng này sử dụng Transaction thứ hai, thì Transaction thứ hai sẽ bị khóa. Nó bị 
khóa vì serializable transaction khóa hàng được truy xuất và Transaction thứ hai không thể lấy một khóa trên 
hàng này. 
Danh sách 14.5 cho thấy một ví dụ về điều này. Transaction thứ hai gán khóa timeout tới 1 giây. Có nghĩa là 
chương trình sẽ ném ra một SqlException đơn giản hơn là treo máy khi Transaction thứ hai không thể làm chủ 
một khóa trên hàng ALFKI trong bảng Customers . 
Danh sách 14.5: Block.c 
/* 
 Block.cs illustrates how a serializable command locks 
 the rows it retrieves so that a second transaction 
 cannot get a lock to update one of these retrieved rows 
 that has already been locked 
*/ 
using System; 
using System.Data; 
using System.Data.SqlClient; 
class Block 
{ 
 public static void DisplayRows( 
 SqlCommand mySqlCommand 
 ) 
 { 
 mySqlCommand.CommandText = 
 "SELECT CustomerID, CompanyName "+ 
 "FROM Customers "+ 
 "WHERE CustomerID IN ('ALFKI', 'J8COM')"; 
 SqlDataReader mySqlDataReader = mySqlCommand.ExecuteReader(); 
 while (mySqlDataReader.Read()) 
 { 
 Console.WriteLine("mySqlDataReader[\" CustomerID\"] = "+ 
 mySqlDataReader["CustomerID"]); 
 Console.WriteLine("mySqlDataReader[\" CompanyName\"] = "+ 
 mySqlDataReader["CompanyName"]); 
 } 
 mySqlDataReader.Close(); 
 } 
 public static void Main() 
 { 
 // create and open two SqlConnection objects 
 SqlConnection serConnection = 
 new SqlConnection( 
 "server=localhost;database=Northwind;uid=sa;pwd=sa" 
 ); 
 SqlConnection rcConnection = 
 new SqlConnection( 
 "server=localhost;database=Northwind;uid=sa;pwd=sa" 
 ); 
 serConnection.Open(); 
 rcConnection.Open(); 
 // create the first SqlTransaction object and start the transaction 
 // by calling the BeginTransaction() method of the SqlConnection 
 // object, passing the IsolationLevel of Serializable to the method 
 SqlTransaction serializableTrans = 
 serConnection.BeginTransaction(IsolationLevel.Serializable); 
 // create a SqlCommand and set its Transaction property 
 // to serializableTrans 
 SqlCommand serializableCommand = 
 serConnection.CreateCommand(); 
 serializableCommand.Transaction = serializableTrans; 
 // call the DisplayRows() method to display rows from 
 // the Customers table; 
 // this causes the rows to be locked, if you comment 
 // out the following line then the INSERT and UPDATE 
 // performed later by the second transaction will succeed 
 DisplayRows(serializableCommand); // * 
 // create the second SqlTransaction object 
 SqlTransaction readCommittedTrans = 
 rcConnection.BeginTransaction(IsolationLevel.ReadCommitted); 
 // create a SqlCommand and set its Transaction property 
 // to readCommittedTrans 
 SqlCommand readCommittedCommand = 
 rcConnection.CreateCommand(); 
 readCommittedCommand.Transaction = readCommittedTrans; 
 // set the lock timeout to 1 second using the 
 // SET LOCK_TIMEOUT command 
 readCommittedCommand.CommandText = "SET LOCK_TIMEOUT 1000"; 
 readCommittedCommand.ExecuteNonQuery(); 
 try 
 { 
 // insert a new row into the Customers table 
 Console.WriteLine("Inserting new row into Customers table "+ 
 "with CustomerID of J8COM"); 
 readCommittedCommand.CommandText = 
 "INSERT INTO Customers ("+ 
 "CustomerID, CompanyName "+ 
 ") VALUES ( " + 
 " 'J8COM', 'J8 Company' "+ 
 ")"; 
 int numberOfRows = readCommittedCommand.ExecuteNonQuery(); 
 Console.WriteLine("Number of rows inserted = "+ numberOfRows); 
 // update the ALFKI row in the Customers table 
 Console.WriteLine("Setting CompanyName to 'Widgets Inc.' for "+ 
 "for row with CustomerID of ALFKI"); 
 readCommittedCommand.CommandText = 
 "UPDATE Customers "+ 
 "SET CompanyName = 'Widgets Inc.' "+ 
 "WHERE CustomerID = 'ALFKI'"; 
 numberOfRows = readCommittedCommand.ExecuteNonQuery(); 
 Console.WriteLine("Number of rows updated = "+ numberOfRows); 
 // display the new rows and rollback the changes 
 DisplayRows(readCommittedCommand); 
 Console.WriteLine("Rolling back changes"); 
 readCommittedTrans.Rollback(); 
 } 
 catch (SqlException e) 
 { 
 Console.WriteLine(e); 
 } 
 finally 
 { 
 serConnection.Close(); 
 rcConnection.Close(); 
 } 
 } 
} 
Cảnh báo: Nếu bạn biên dịch và chạy chương trình này như nó có, thì nó sẽ ném một SqlException. Đây là sự 
ước định trước, như nó cho bạn thấy sự nỗ lực để lấy một khóa time out. Nếu bạn chuyển lệnh gọi đầu tiên tới 
phương thức DisplayRows() thành một ghi chú trong chương trình này [ Đánh dấu với một dấu sao (*)], thì 
chương trình sẽ không ném ra một SqlException. Vì đây là ghi chú (lệnh gọi đầu tiên tới DisplayRows() )nó tách 
serializable transaction khỏi việc truy xuất và do đó khóa những hàng. và Transaction thứ hai có thể lấy khóa 
trên hàng ALFKI. 
Đầu ra từ chương trình này như sau (chú ý nó ném ra một SqlException khi vượt quá thời gian timeout của 
khóa ): 
mySqlDataReader["CustomerID"] = ALFKI 
mySqlDataReader["CompanyName"] = Alfreds Futterkiste 
Inserting new row into Customers table with CustomerID of J8COM 
System.Data.SqlClient.SqlException: Lock request time out period exceeded. 
 at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, 
 TdsParserState state) 
 at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, 
 TdsParserState state) 
 at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning() 
 at System.Data.SqlClient.TdsParser.Run(RunBehavior run, SqlCommand cmdHandler, 
 SqlDataReader dataStream) 
 at System.Data.SqlClient.SqlCommand.ExecuteNonQuery() 
 at Block.Main() 
Thử chuyển thành ghi chú đọan lệnh gọi đầu tiên tới DisplayRows() trong chương trình, và sau đó biên dịch lại 
và chạy nó lần nữa. Lần này giao dịch thứ hai sẽ có khả năng để lấy khóa trên hàng và tiến hành. 
Những bế tắc 
Một sự bế tắc xuất hiện khi hai giao dịch đang đợi những khóa mà giao dịch khác hiện thời có. Xem xét hai giao 
dịch sau: 
Transaction 1 (T1): 
BEGIN TRANSACTION 
UPDATE Customers 
SET CompanyName = 'Widgets Inc.' 
WHERE CustomerID = 'ALFKI' 
UPDATE Products 
SET ProductName = 'Widget' 
WHERE ProductID = 1 
COMMIT TRANSACTION 
Transaction 2 (T2): 
BEGIN TRANSACTION 
UPDATE Products 
SET ProductName = ' Chai' 
WHERE ProductID = 1 
UPDATE Customers 
SET CompanyName = ' Alfreds Futterkiste' 
WHERE CustomerID = 'ALFKI' 
COMMIT TRANSACTION 
Chú ý: cả T1 lẫn T2 đều cập nhật cùng những hàng như nhau trong bảng Customers và Products. Nếu T1 và T2 
được thực thi kế tiếp nhau vào những thời gian khác nhau, T1 được thực hiện rồi hoàn thành, theo sau là T2, thì 
không có sự cố gì. Tuy nhiên, nếu T1 và T2 được thực hiện cùng lúc với những sự phát biểu Cập nhật của chúng , 
thì một sự bế tắc xuất hiện. Hãy xem xét một ví dụ về điều này, sử dụng những bước sau đây: 
1. T1 bắt đầu. 
2. T2 bắt đầu. 
3. T1 khóa hàng Customers và cập nhật hàng. 
4. T2 khóa hàng Products và cập nhật hàng. 
5. T2 đợi khóa trên hàng Products, mà hiện thời được giữ bởi T1. 
6. T1 đợi khóa trên hàng Customers, mà hiện thời được giữ bởi T2. 
Trong bước 5, T2 đợi một khóa giữ bởi T1. Trong bước 6, T1 đợi một khóa giữ bởi T2. Như vậy, một sự bế tắc 
xuất hiện khi cả hai giao dịch đang đợi lẫn nhau. Cả hai giao dịch giữ qua lại những khóa yêu cầu. Máy chủ phục 
vụ SQL sẽ phát hiện ra bế tắc và hồi nguyên một trong số những giao dịch. Máy chủ phục vụ SQL hồi nguyên 
những giao dịch rẻ nhất để huỷ, và cũng trả về một lỗi cho biết một bế tắc xuất hiện. 
Bạn cũng có thể chọn giao dịch mà sẽ được hồi nguyên sử dụng lệnh T- SQL SET DEADLOCK_ PRIORITY, 
nó sử dụng cú pháp sau đây: 
SET DEADLOCK_PRIORITY { LOW | NORMAL | @variable } 
VỚI: 
 LOW: chỉ báo giao dịch có một quyền ưu tiên thấp và là cái để hồi nguyên trong sự kiện bế tắc. 
 NORMAL: chỉ báo rằng quy tắc mặc định đang được áp dụng, có nghĩa giao dịch ít đắt nhất được hồi 
nguyên. 
 @variable : là một biến ký tự T- SQL bạn gán là 3 cho LOW hoặc 6 cho NORMAL. 
Chẳng hạn, lệnh sau đây gán DEADLOCK_PRIORITY tới LOW 
SET DEADLOCK_PRIORITY LOW 
Bạn cũng có thể thực thi lệnh SET DEADLOCK_PRIORITY trong mã C#. Chẳng hạn: 
t2Command.CommandText = "SET DEADLOCK_PRIORITY LOW"; 
t2Command.ExecuteNonQuery(); 
Mẹo nhỏ 
Bạn có thể giảm bớt nguy cơ về một sự bế tắc xuất hiện trong chương trình của bạn bởi việc giữ những giao dịch 
của các bạn càng ngắn càng tốt; bằng cách này, những khóa được giữ trong những đối tượng cơ sở dữ liệu trong 
thời gian ngắn nhất có thể. Bạn cũng cần phải truy cập những bảng trong cùng một thứ tự như vậy khi thực thi 
nhiều giao dịch cùng lúc; bằng cách này, bạn giảm bớt nguy cơ về giao dịch giữ qua lại những khóa yêu cầu. 
Danh sách 14.6 cho thấy một chương trình minh họa hai giao dịch T1 và T2 làm bế tắc trong sự kiện được mô tả 
trước . Mỗi sự Cập nhật được thực hiện sử dụng một luồng riêng biệt để mô phỏng những sự Cập nhật được trình 
bày trong sáu bước trước. 
Danh sách 14.6: Deadlock.c 
/* 
 Deadlock.cs illustrates how two transactions can 
 deadlock each other 
*/ 
using System; 
using System.Data; 
using System.Data.SqlClient; 
using System.Threading; 
class Deadlock 
{ 
 // create two SqlConnection objects 
 public static SqlConnection t1Connection = 
 new SqlConnection( 
 "server=localhost;database=Northwind;uid=sa;pwd=sa" 
 ); 
 public static SqlConnection t2Connection = 
 new SqlConnection( 
 "server=localhost;database=Northwind;uid=sa;pwd=sa" 
 ); 
 // declare two SqlTransaction objects 
 public static SqlTransaction t1Trans; 
 public static SqlTransaction t2Trans; 
 // declare two SqlCommand objects 
 public static SqlCommand t1Command; 
 public static SqlCommand t2Command; 
 public static void UpdateCustomerT1() 
 { 
 // update the row with a CustomerID of ALFKI 
 // in the Customers table using t1Command 
 Console.WriteLine("Setting CompanyName to 'Widgets Inc.' "+ 
 "for row with CustomerID of ALFKI using t1Command"); 
 t1Command.CommandText = 
 "UPDATE Customers "+ 
 "SET CompanyName = 'Widgets Inc.' "+ 
 "WHERE CustomerID = 'ALFKI'"; 
 int numberOfRows = t1Command.ExecuteNonQuery(); 
 Console.WriteLine("Number of rows updated = "+ numberOfRows); 
 } 
 public static void UpdateProductT2() 
 { 
 // update the row with a ProductID of 1 
 // in the Products table using t2Command 
 Console.WriteLine("Setting ProductName to 'Widget' "+ 
 "for the row with ProductID of 1 using t2Command"); 
 t2Command.CommandText = 
 "UPDATE Products "+ 
 "SET ProductName = 'Widget' "+ 
 "WHERE ProductID = 1"; 
 int numberOfRows = t2Command.ExecuteNonQuery(); 
 Console.WriteLine("Number of rows updated = "+ numberOfRows); 
 } 
 public static void UpdateProductT1() 
 { 
 // update the row with a ProductID of 1 
 // in the Products table using t1Command 
 Console.WriteLine("Setting ProductName to 'Chai' "+ 
 "for the row with ProductID of 1 using t1Command"); 
 t1Command.CommandText = 
 "UPDATE Products "+ 
 "SET ProductName = 'Chai' "+ 
 "WHERE ProductID = 1"; 
 int numberOfRows = t1Command.ExecuteNonQuery(); 
 Console.WriteLine("Number of rows updated = "+ numberOfRows); 
 } 
 public static void UpdateCustomerT2() 
 { 
 // update the row with a CustomerID of ALFKI 
 // in the Customers table using t2Command 
 Console.WriteLine("Setting CompanyName to 'Alfreds Futterkiste' "+ 
 "for row with CustomerID of ALFKI using t2Command"); 
 t2Command.CommandText = 
 "UPDATE Customers "+ 
 "SET CompanyName = 'Alfreds Futterkiste' "+ 
 "WHERE CustomerID = 'ALFKI'"; 
 int numberOfRows = t2Command.ExecuteNonQuery(); 
 Console.WriteLine("Number of rows updated = "+ numberOfRows); 
 } 
 public static void Main() 
 { 
 // open the first connection, begin the first transaction, 
 // and set the lock timeout to 5 seconds 
 t1Connection.Open(); 
 t1Trans = t1Connection.BeginTransaction(); 
 t1Command = t1Connection.CreateCommand(); 
 t1Command.Transaction = t1Trans; 
 t1Command.CommandText = "SET LOCK_TIMEOUT 5000"; 
 t1Command.ExecuteNonQuery(); 
 // open the second connection, begin the second transaction, 
 // and set the lock timeout to 5 seconds 
 t2Connection.Open(); 
 t2Trans = t2Connection.BeginTransaction(); 
 t2Command = t2Connection.CreateCommand(); 
 t2Command.Transaction = t2Trans; 
 t2Command.CommandText = "SET LOCK_TIMEOUT 5000"; 
 t2Command.ExecuteNonQuery(); 
 // set DEADLOCK_PRIORITY to LOW for the second transaction 
 // so that it is the transaction that is rolled back 
 t2Command.CommandText = "SET DEADLOCK_PRIORITY LOW"; 
 t2Command.ExecuteNonQuery(); 
 // create four threads that will perform the interleaved updates 
 Thread updateCustThreadT1 = new Thread(new ThreadStart(UpdateCustomerT1)); 
 Thread updateProdThreadT2 = new Thread(new ThreadStart(UpdateProductT2)); 
 Thread updateProdThreadT1 = new Thread(new ThreadStart(UpdateProductT1)); 
 Thread updateCustThreadT2 = new Thread(new ThreadStart(UpdateCustomerT2)); 
 // start the threads to actually perform the interleaved updates 
 updateCustThreadT1.Start(); 
 updateProdThreadT2.Start(); 
 updateProdThreadT1.Start(); 
 updateCustThreadT2.Start(); 
 } 
} 
Ghi chú: 
Bạn có thể nghĩ về một luồng như một quá trình riêng biệt trong chương trình của bạn, và mỗi luồng xuất 
hiện để thực hiện trong đường song song với những luồng khác.Về một thảo luận chi tiết của những luồng, 
xem cuốn sách "Mastering Visual C# .NET" do Jason Price và Mike Gunderloy ( Sybex, 2002). 
Chương trình trình bày trong Danh sách 14.6 chứa những phương thức sau đây: 
 UpdateCustomerT1() Cập nhật hàng với một CustomerID là ALFKI trong bảng Customers sử dụng giao 
dịch đầu tiên. Đặc biệt, nó đặt CompanyName tới Widgets Inc. 
 UpdateProductT2() Cập nhật hàng với một ProductID là 1 trong bảng Products sử dụng giao dịch thứ 
hai. Đặc biệt, nó đặt ProductName tới Widget. 
 UpdateProductT1() Cập nhật hàng với ProductID là 1 trong bảng Products sử dụng sự giao dịch đầu 
tiên. Đặc biệt, nó đặt ProductName tới Chai. 
 UpdateCustomerT2() Cập nhật hàng với một CustomerID là ALFKI trong bảng Customers sử dụng 
giao dịch thứ hai. Đặc biệt nó đặt CompanyName tới Alfreds Futterkiste. 
Những phương thức này sẽ được gọi bởi những luồng để thực hiện cập nhật được đặt xen kẽ. 
Ghi chú 
Chương trình này chỉ báo giao dịch thứ hai sẽ được hồi nguyên khi sự bế tắc xuất hiện sử dụng lệnh SET 
DEADLOCK_PRIORITY LOW. 
Đầu ra của chương trình này như sau: 
Setting CompanyName to 'Widgets Inc.' for row 
 with CustomerID of ALFKI using t1Command 
Number of rows updated = 1 
Setting ProductName to 'Widget' for the row 
 with ProductID of 1 using t2Command 
Number of rows updated = 1 
Setting ProductName to 'Chai' for the row 
 with ProductID of 1 using t1Command 
Setting CompanyName to 'Alfreds Futterkiste' for row 
 with CustomerID of ALFKI using t2Command 
Ngoại lệ Unhandled ( không sử lý được): 
 System.Data.SqlClient.SqlException: Giao dịch ( ID Quá trình 53) bị bế tắc trên 
 {sự khóa} những tài nguyên với quá trình khác và đã được lựa chọn như nạn nhân bế tắc. 
 chạy lại giao dịch. 
 Tại System.Data.SqlClient.SqlConnection.OnError(ngoại lệ,Trạng thái TdsParserState) 
 Tại System.Data.SqlClient.SqlInternalConnection.OnError(ngoại lệ,Trạng thái TdsParserState) 
 tại System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning() 
 tại System.Data.SqlClient.TdsParser.Run(Sự chạy RunBehavior, cmdHandler SqlCommand 
 Dòng dữ liệu SqlDataReader) 
 Tại System.Data.SqlClient.SqlCommand.ExecuteNonQuery() 
 Tại Deadlock.UpdateCustomerT2() 
 Number of rows updated = 1 
Tóm lược 
Ngày nay, những cơ sở dữ liệu có thể xử lý nhiều người sử dụng và những chương trình truy cập cơ sở dữ liệu 
tại cùng thời điểm, mỗi cái chạy một cách tiềm tàng những giao dịch của chúng trong cơ sở dữ liệu. Phần mềm 
cơ sở dữ liệu phải có khả năng để thỏa mãn những nhu cầu của tất cả những giao dịch trùng hợp này, cũng như 
bảo trì sự toàn vẹn của những hàng được cất giữ trong những bảng cơ sở dữ liệu. Bạn có thể kiểm soát lượng cô 
lập tồn tại giữa những giao dịch của bạn và những giao dịch khác mà có lẽ đang được chạy trong cơ sở dữ liệu. 
Trong chương này, bạn đã đi sâu vào trong điều khiển giao dịch tiên tiến sử dụng Máy chủ phục vụ SQL và 
ADO.NET. Đặc biệt, bạn đã thấy cách thiết đặt một savepoint, hồi nguyên một giao dịch đến savepoint này, và 
đặt mức cô lập giao dịch. Bạn cũng học về những khóa của máy chủ phục vụ SQL và những giao dịch có thể 
khóa và gây bế tắc lẫn nhau như thế nào. 
Trong chương kế tiếp, bạn sẽ học về XML. 
CHUƠNG 15: GIỚI THIỆU VỀ NHỮNG ỨNG DỤNG WEB-ASP.NET 
Tổng quan 
Những trang Máy chủ phục vụ họat động cho mạng (ASP.NET) cho phép bạn tạo ra những trang Web động với 
nội dung có thể thay đổi trong thời gian chạy và để phát triển những ứng dụng truy cập được, sử dụng một trình 
duyệt Web (Web browser). ví dụ, bạn đã có thể phát triển một ứng dụng thương mại điện tử cho phép những 
người sử dụng đặt mua những sản phẩm qua Mạng, hay một ứng dụng thương mại cổ phần, điều đó cho phép 
những người sử dụng đặt những những cổ phiếu thương mại trong những công ty. 
ASP.NET được nhận thức tương tự như những trang JavaServer đối thủ của nó (JSP) trong đó bạn đòi hỏi một 
trang từ một Máy chủ phục vụ, sử dụng một trình duyệt Web, và máy chủ phục vụ đáp ứng bởi việc chạy trang 
ASP.NET.Rồi Máy chủ phục vụ gửi trả HTML được hiển thị trong trỉnh duyệt của bạn. 
Trong chương này bạn sẽ học cơ sở của ASP.NET, và bạn sẽ thấy cách sử dụng Visual Studio .NET như thế nào 
để tạo ra những ứng dụng ASP.NET sử dụng C# làm ngôn ngữ lập trình. Những đặc trưng trong chương này: 
 ■ Tạo ra những ứng dụng Web ASP.NET 
 ■ Những điều khiển Web form 
 ■ Sử dụng những điều khiển DataGrid và DataList để truy cập một cơ sở dữ liệu 
 ■ Bảo trì trạng thái trong một ứng dụng Mạng 
 ■ Tạo ra một ứng dụng mua hàng đơn giản 
TẠO MỘT TRÌNH ỨNG DỤNG WEB ASP.NET ĐƠN GIẢN SỬ DỤNG VS.NET 
Trong mục này, bạn sẽ thấy cách tạo ra một ứng dụng Web ASP .NET đơn giản chứa một cái hộp văn bản và 
một nút- sử dụng VS .NET. Khi bạn nhấn nút, một chuỗi văn bản sẽ xuất hiện trong hộp văn bản của bạn. Bạn sẽ 
học cách để triển khai ứng dụng này tới máy chủ phục vụ thông tin Internet của Microsoft (IIS) như thế nào. Bạn 
cũng sẽ thấy cách chạy ứng dụng Web ví dụ từ Internet Explorer. 
Ghi chú: 
IIS là phần mềm cho phép bạn chạy những ứng dụng Web ASP.NET và hiển thị những trang HTML. Để 
triển khai những ứng dụng ASP.NET trình bày trong chương này, bạn sẽ cần truy cập tới một máy tính có 
chạy IIS, cùng với những mở rộng của máy chủ phục vụ FrontPage. Những mở rộng này cho phép bạn 
triển khai một ứng dụng Web ASP.NET từ Visual Studio .NET. Bạn có thể tìm thấy thông tin đầy đủ về 
việc thiết đặt IIS Và những mở rộng của máy chủ phục vụ FrontPage trong tài liệu trợ giúp trực tuyến 
Windows; để truy cập tài liệu này, chọn Start ¾- Help. 
Thực hiện những bước sau đây: 
1. Khởi động Visual Studio .NET (VS .NET) và chọn File - New Project. chọn Visual C# Projects từ vùng 
Project Types bên trái hộp thoại New Project, và chọn ASP .NET Web Application từ vùng Templates 
area ( khung mẫu ) ở bên phải. nhập vào http: // Localhost/ MyWeb- Application trong Location field 
(trường định vị), như trong Hình 15.1. 
 Hình 15.1: tạo ra một ứng dụng Mạng ASP.NET trong Visual Studio .NET 
Ghi nhớ: tên localhost đại diện cho máy tính địa phương của bạn, trên đó bạn đang phát triển ứng dụng 
Mạng của bạn. Nếu bạn đang sử dụng IIS mà đang chạy trên một máy tính khác với máy tính địa phương 
của bạn, bạn cần phải thay thế localhost với tên của máy tính từ xa. 
2. Kích nút Ok để tiếp tục. VS.NET sẽ tạo ra một thư mục mới có tên MyWebApplication trong thư mục 
wwwroot; đây là thư mục nơi IIS cất giữ những trang Web và ứng dụng xuất bản. Sau khi bạn kích nút Ok, 
bạn sẽ thấy ứng dụng mới đang được gửi tới IIS. 
 Một khi ứng dụng của bạn đã được triển khai tới IIS, VS .NET sẽ trình bày một form Web để trống. Bạn 
có thể hiểu form Web như tấm vải bạt mà trên đó bạn có thể đặt những điều khiển, thídụ như những hộp 
văn bản và những nút. Và sau đó khi bạn chạy form của bạn, bạn sẽ thấy trang này được trình bày bởi trình 
duyệt Web được đặt trong một dáng vẻ tương tự tới form của các bạn. 
3. Thêm một điều khiển TextBox vào form của bạn. Giá trị ngầm định cho thuộc tính ID của điều khiển 
TextBox của bạn là TextBox1. 
Ghi nhớ: Bạn sử dụng thuộc tính ID khi tham chiếu một điều khiển web trong mã C#. Bạn sẽ thấy một ví 
dụ của mã thự hiện điều này không lâu nữa. 
4. Gán thuộc tính TextMode cho TextBox1 là MultiLine; Điều này cho phép văn bản sẽ được trình bày trên 
nhiều hàng. Tiếp theo, thêm một điều khiển Nút vào form . ID mặc định cho điều khiển Nút là Button1. 
Đặt thuộc tính Text cho Button1 là "Press me!" Hình 15.2 cho thấy form với TextBox và những điều khiển 
Button. 
 Hình 15.2: Thêm TextBox và những điều khiển Button vào form 
5. Tiếp theo, bạn sẽ thêm một hàng mã tới phương thức Button1_Click() . Phương thức này được thực hiện 
khi Button1 được nhấn trong khi form chạy. Phát biểu mà bạn thêm vào Button1_Click() sẽ gán thuộc tính 
Text của TextBox1 tới một chuỗi. Chuỗi này chứa một hàng "Romeo and Juliet" của Shakespeare . Để 
thêm mã, nhấn đúp Button1 và nhập vào mã sau đây trong phương thức Button1_Click() : 
TextBox1.Text = 
 "But, soft! what light through yonder window breaks?\n" + 
 "It is the east, and Juliet is the sun.\n" + 
 "Arise, fair sun, and kill the envious moon,\n" + 
 "Who is already sick and pale with grief,\n" + 
 "That thou her maid art far more fair than she"; 
Ghi chú: Nếu bạn là một người hâm mộ Shakespeare, bạn sẽ nhận ra những hàng này từ cảnh ban 
công lộng lẫy mà trong đó Romeo thốt lên tình yêu chân thành của anh ấy với Juliet. 
6. Bây giờ bạn sẵn sàng để chạy form của bạn. Chọn Debug - Start Without Debugging, hay nhấn Ctrl+ F5 
trên bàn phím để chạy form của bạn (xem Hình 15.3). 
 Hình 15.3: Form đang chạy 
Bây giờ bạn đã tạo được và chạy form, chúng ta hãy khảo sát mã được phát sinh bởi VS .NET. Có hai phần 
chính với mã: 
 File WebForm1.aspx , chứa mã HTML và ASP.NET . 
 File WebForm1.aspx.cs , chứa mã C# hỗ trợ web form. Bạn có thể hiểu mã C# này như một thứ sự chạy 
đằng sau form, và vì lý do này File WebForm1.aspx.cs được biết như file sau mã. 
 Ghi nhớ: phần mở rộng .Aspx xác định những file ASP .NET. 
Bạn sẽ khảo sát những chi tiết của WebForm1.aspx và file WebForm1.aspx.cs trong những mục sau đây. 
File WebForm1.aspx 
Bạn có thể xem HTML chứa chững nhãn ASP.NET cho form của bạn bởi việc kích chuỗi liên kết HTML ở đáy 
của cửa sổ thiết kế form. Kích mối liên kết HTML để xem mã cho form của bạn. Danh sách 15.1 cho thấy nội 
dung của file WebForm1.aspx . 
Danh sách 15.1: WebForm1.aspx 
<%@ Page language="c#" Codebehind="WebForm1.aspx.cs" 
 AutoEventWireup="false" 
 Inherits="MyWebApplication.WebForm1" %> 
 WebForm1 
 <meta content="" 
 name="vs_targetSchema"> 
 <asp:TextBox id="TextBox1" style="Z-INDEX: 101; LEFT: 13px; 
 POSITION: absolute; TOP: 11px" runat="server" 
 Width="386px" Height="212px" 
 TextMode="MultiLine"> 
 <asp:Button id="Button1" style="Z-INDEX: 102; LEFT: 17px; 
 POSITION: absolute; TOP: 231px" runat="server" Width="82px" Height="22px" 
 Text="Press Me!"> 
Ghi nhớ : những giá trị chính xác cho những vị trí và những kích thước của những điều khiển trong mã 
của mình có lẽ đã hơi khác so với những gì trình bày trong danh sách 15.1. 
Chúng ta hãy khảo sát những hàng trong file này. dòng đầu tiên là 
<%@ Page language="c#" Codebehind="WebForm1.aspx.cs" 
 AutoEventWireup="false" 
 Inherits="MyWebApplication.WebForm1" %> 
Thuộc tính language cho biết file sử dụng ngôn ngữ C#. Thuộc tính Codebehind cho biết file sau mã hỗ trợ form, 
và trong trường hợp này, file sau mã là Web- Form1.aspx.cs. Thuộc tính AutoEventWireUp cho biết liệu khung 
framwork ASP .NET có tự động gọi những phương thức xử lý sự kiện Page_Init() và Page_Load() hay không . 
Những phương thức này được định nghĩa trong WebForm1.aspx.cs; bạn sẽ học nhiều hơn về những phương thức 
xử lý sự kiện này không lâu nữa. Thuộc tính Inherits (kế thừa) chỉ rõ tên của lớp trong file WebForm1.aspx.cs từ 
đó form thừa kế. 
Vài hàng tiếp theo là HTML tiêu chuẩn nó chỉ rõ đầu mục và meta-information mô tả file. 
 WebForm1 
 <meta content="" 
 name="vs_targetSchema"> 
Hàng kế tiếp bắt đầu thân của file: 
Thuộc tính MS_POSITIONING cho biết những điều khiển form được đặt trong một lưới. Giải pháp cho 
GridLayout là LinearLayout, chỉ rõ là những điều khiển form sẽ được đặt cái này sau cái khác trong trình duyệt. 
Hàng kế tiếp bắt đầu một form: 
Thuộc tính ID chỉ rõ tên của form là Form1. Thuộc tính method (phương thức) chỉ báo form sử dụng một thông 
báo cần thiết HTTP để gửi thông tin cho máy chủ phục vụ. Thuộc tính runat chỉ rõ form được thực thi trên máy 
chủ phục vụ. 
Những hàng kế tiếp chứa những chi tiết của điều khiển TextBox mà bạn thêm vào form của bạn 
<asp:TextBox id="TextBox1" style="Z-INDEX: 101; LEFT: 13px; 
 POSITION: absolute; TOP: 11px" runat="server" 
 Width="386px" Height="212px" 
 TextMode="MultiLine"> 
Những hàng kế tiếp chứa những chi tiết của điều khiển Nút mà bạn thêm vào form của bạn 
<asp:Button id="Button1" style="Z-INDEX: 102; LEFT: 17px; 
 POSITION: absolute; TOP: 231px" runat="server" 
 Width="82px" Height="22px" Text="Press Me!"> 
Những hàng còn lại trong file WebForm1.aspx kết thúc form, thân và file: 
File WebForm1.aspx.cs 
File WebForm1.aspx.cs chứa mã đằng sau form của bạn. Bạn có thể xem mã này bởi chọn View - Code, hay Bạn 
có thể nhấn F7 trên bàn phím . 
Danh sách 15.2 cho thấy nội dung của file WebForm1.aspx.cs . 
Danh sách 15.2: WebForm1.aspx.cs 
using System; 
using System.Collections; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.Web; 
using System.Web.SessionState; 
using System.Web.UI; 
using System.Web.UI.WebControls; 
using System.Web.UI.HtmlControls; 
namespace MyWebApplication 
{ 
 /// 
 /// Summary description for WebForm1. 
 /// 
 public class WebForm1 : System.Web.UI.Page 
 { 
 protected System.Web.UI.WebControls.TextBox TextBox1; 
 protected System.Web.UI.WebControls.Button Button1; 
 private void Page_Load(object sender, System.EventArgs e) 
 { 
 // Put user code to initialize the page here 
 } 
 #region Web Form Designer generated code 
 override protected void OnInit(EventArgs e) 
 { 
 // 
 // CODEGEN: This call is required by the ASP.NET Web Form Designer. 
 // 
 InitializeComponent(); 
 base.OnInit(e); 
 } 
 /// 
 /// Required method for Designer support - do not modify 
 /// the contents of this method with the code editor. 
 /// 
 private void InitializeComponent() 
 { 
 this.Button1.Click += new System.EventHandler(this.Button1_Click); 
 this.Load += new System.EventHandler(this.Page_Load); 
 } 
 #endregion 
 private void Button1_Click(object sender, System.EventArgs e) 
 { 
 TextBox1.Text = 
 "But, soft! what light through yonder window breaks?\n" + 
 "It is the east, and Juliet is the sun.\n" + 
 "Arise, fair sun, and kill the envious moon,\n" + 
 "Who is already sick and pale with grief,\n" + 
 "That thou her maid art far more fair than she"; 
 } 
 } 
} 
Như bạn có thể thấy, lớp WebForm1 được bắt nguồn từ lớp System.Web.UI.Page . Trong thực tế, khi bạn chạy 
form, .NET thật sự tạo ra một đối tượng của lớp Page đại diện cho form của bạn. 
Lớp WebForm1 khai báo hai đối tượng được bảo vệ có tên TextBox1 và Button1, nó đại diện cho những điều 
khiển TextBox và Nút bạn thêm vào form của bạn. 
Phương thức xử lý sự kiện Page_Load() được gọi khi sự kiện Page_Load được khởi dậy. Sư kiện Page_Load 
được khởi dậy mỗi khi form web được tải bởi một trình duyệt. Điển hình, bạn sẽ đặt bất kỳ mã khởi tạo nào 
trong phương thức Page_Load(). Chẳng hạn, nếu bạn muốn truy cập một cơ sở dữ liệu, bạn mở kết nối cơ sở dữ 
liệu trong phương thức Page_Load(). 
Những phương thức OnInit() và InitializeComponent() được đặt bên trong những bộ định hướng tiền xử lý # 
region và # endregion. Những bộ định hướng này bao bọc một vùng mã mà có thể được thu gom lại trong cửa sổ 
biên tập mã VS .NET, chỉ để lại văn bản mà ngay lập tức hiển thị đàng sau nút # region. 
Phương thức OnInit() được gọi khi form khởi chạy. Phương thức này gọi phương thức InitializeComponent() và 
thêm những sự kiện Button Click và form Load tới đối tượng System.EventHandler. Điều này cho thông tin hệ 
thống mà hai sự kiện này sẽ được xử lý bởi những phương thức Button1_Click() Và Page_Load(), tương ứng. 
Phương thức Button1_Click() là phương thức bạn sửa đổi trước đó với mã gán thuộc tính Text của điều khiển 
TextBox1 của bạn tới một chuỗi đang chứa lời trích dẫn từ Romeo và Juliet. 
Trong mục kế tiếp, bạn sẽ được giới thiệu về vài điều khiển khác bạn có thể thêm vào một form web. 
Những điều khiển Form Web 
Trong mục này, bạn sẽ xem một tóm lược về nhiều lọai điều khiển form web mà bạn có thể lấy từ mục những 
form web của Toolbox. Bảng 15.1 tổng kết những điều khiển. 
Bảng 15.1: những điều khiển form web 
Điều khiển Mô tả 
Label Hiển thị văn bản. Bạn gán văn bản mà bạn muốn trình bày sử dụng thuộc tính Text. 
TextBox Một hộp chứa văn bản mà người sử dụng form của bạn có thể soạn thảo khi chạy 
chương trình. Thuộc tính TextMode có thể được gán tới SingleLine (văn bản xuất 
hiện trên một hàng), MultiLine (văn bản xuất hiện trên nhiều hàng), và Password 
(văn bản xuất hiện dưới dạng ký tự sao). Thuộc tính Text chứa văn bản của 
TextBox. 
Button Một nút có thể nhấn. Thuộc tính Text xác định văn bản hiển thị trên nút. 
LinkButton Tương tự như một nút, ngọai trừ một LinkButton xuất hiện như một mối liên kết 
siêu văn bản. Bạn gán mối liên kết sử dụng thuộc tính Text. 
ImageButton Tương tự như một nút, ngọai trừ một ImageButton trình bày một ảnh. Bạn gán ảnh 
sử dụng thuộc tính ImageUrl. 
HyperLink Một hyperlink (liên kết siêu van bản). Bạn đặt hyperlink sử dụng thuộc tính 
NavigateUrl. 
DropDownList Một danh sách của những tùy chọn được sổ xuống khi kích. Bạn gán danh sách 
những tùy chọn sử dụng thuộc tính Items. Người sử dụng chỉ có thể chọn một tùy 
chọn từ DropDownList khi form chạy. 
ListBox Một danh sách những tùy chọn. Bạn gán danh sách những tùy chọn sử dụng thuộc 
tính Items. Người sử dụng có thể chọn nhiều tùy chọn từ ListBox nếu thuộc tính 
SelectionMode được gán tới Multiple. Giá trị khác là Single, trong trường hợp này 
người sử dụng chỉ có thể chọn một tùy chọn. 
DataGrid Một khung lưới chứa dữ liệu truy xuất từ một nguồn dữ liệu, ví dụ một cơ sở dữ 
liệu. Bạn gán nguồn dữ liệu sử dụng thuộc tính DataSource. 
DataList Một danh sách đang chứa dữ liệu truy xuất từ một nguồn dữ liệu. Bạn gán nguồn 
dữ liệu sử dụng thuộc tính DataSource. 
Repeater Một danh sách chứa dữ liệu được truy xuất từ một nguồn dữ liệu mà bạn gán sử 
dụng thuộc tính DataSource. Mỗi mục trong danh sách có thể được trình bày sử 
dụng một template (khung mẫu). Một khung mẫu định nghĩa nội dung và cách trình 
bày của những tiết mục trong danh sách. 
CheckBox Một hộp kiểm chứa một giá trị Boole true/ false được gán tới true bởi người sử 
dụng nếu họ chọn hộp kiểm . Thuộc tính Checked cho biết giá trị Boole hiện thời 
được gán trong hộp kiểm . 
CheckBoxList Một hộp kiểm nhiều chọn lựa . Bạn gán danh sách cho những hộp kiểm sử dụng 
thuộc tính Items. 
RadioButton Một nút rađiô chứa một giá trị Boole true/ false được gán là true bởi người sử dụng 
nếu họ nhấn chọn nút. Thuộc tính Checked cho biết giá trị Boole hiện thời được 
gán trong nút rađiô. 
RadioButtonList Một nhóm những nút rađiô. Bạn gán danh sách những nút rađiô sử dụng thuộc tính 
Items. 
Image Hiển thị một ảnh mà bạn gán sử dụng thuộc tính ImageUrl. 
Panel Một côngtenơ ( vật chứa) những điều khiển khác. 
PlaceHolder Một côngtenơ cho những điều khiển mà bạn có thể tạo ra trong thời gian chạy 
chương trình; những điều được biết như những sự điều khiển động. 
Calendar Trình bày một lịch trong một tháng và cho phép người sử dụng chọn một ngày 
tháng và có thể định hướng tới tháng tới hoặc tháng trước. Bạn sử dụng thuộc tính 
SelectedDate để lấy hay đặt ngày tháng được chọn, và bạn sử dụng thuộc tính 
VisibleDate để lất hay gán tháng hiện thời được trình bày. 
AdRotator Trình bày những bảng thông cáo. Chi tiết về những thông cáo, như ảnh, URL khi 
được kích, và tần số hiển thị, được thiết đặt trong một file XML sử dụng thuộc tính 
AdvertisementFile. 
Table Trình bày một bảng với những hàng, mà bạn gán sử dụng thuộc tính Rows. 
RequiredFieldValidator Để bảo đảm rằng người sử dụng đã chỉ định đầu vào nào đó cho một điều khiển. 
Bạn gán điều khiển đến hiệu lực hóa sử dụng thuộc tính ControlToValidate. Bạn sẽ 
thấy một ví dụ sử dụng một điều khiển được hiệu lực hóa không lâu nữa. 
CompareValidator Để so sánh một mục nhập do một người sử dụng nhập vào trong một điều khiển với 
điều khiển khác hay một giá trị hằng. Bạn gán điều khiển để làm cho có hiệu lực sử 
dụng thuộc tính ControlToValidate (điều khiển này chứa giá trị được nhập vào bởi 
người sử dụng). Bạn đặt điều khiển để so sánh với, sử dụng thuộc tính 
ControlToCompare hay thuộc tính ValueToCompare. Bạn đặt toán tử cho sự so 
sánh sử dụng thuộc tính Operator. 
RangeValidator Để bảo đảm rằng người sử dụng đã nhập vào một giá trị bên trong một phạm vi 
được chỉ rõ trong một điều khiển. Bạn gán điều khiển để hiệu lực hóa nó sử dụng 
thuộc tính ControlToValidate , và phạm vi của những giá trị sử dụng những thuộc 
tính MinimumValue và MaximumValue. 
RegularExpressionValidator Để bảo đảm rằng người sử dụng đã nhập vào một giá trị thỏa mãn một biểu thức 
thông thường được chỉ định. Bạn đặt điều khiển để hiệu lực hóa nó sử dụng thuộc 
tính ControlToValidate , và biểu thức thông thường sử dụng thuộc tính 
ValidationExpression. 
CustomValidator Để thực hiện sự hiệu lực hóa theo ý riêng của mình cho giá trị nhập vào bởi người 
sử dụng. Bạn đặt điều khiển để hiệu lực hóa nó, sử dụng thuộc tính 
ControlToValidate, và hàm sử dụng trong sự hiệu lực hóa của bạn, sử dụng thuộc 
tính ClientValidationFunction. 
ValidationSummary Để trình bày một tóm lược của tất cả các lỗi về sự hiệu lực hóa trên form web và/ 
hoặc một hộp thoại. Bạn thiết đặt thuộc tính ShowSummary để sác định liệu Bạn có 
muốn trình bày những lỗi trên form web của bạn không, và Bạn thiết đặt cho thuộc 
tính ShowMessageBox để sách định bạn có muốn trình bày những lỗi trong một 
hộp thoại không. 
XML Trình bày nội dung của một file XML. Bạn đặt file XML để trình bày sử dụng 
thuộc tính DocumentSource. 
Literal Hiển thị văn bản tĩnh. Bạn đặt văn bản để trình bày sử dụng thuộc tính Text. 
Bạn sẽ thấy cách sử dụng một số những điều khiển này trong phần còn lại của chương này. 
Xây dựng một ứng dụng phức tạp hơn 
Trong mục này, bạn sẽ thấy một web form phức tạp hơn sử dụng những điều khiển Label, TextBox, 
RadioButtonList, DropDownList, và RequiredFieldValidator. Form sẽ nhắc người sử dụng về tên của chúng 
(một trường được yêu cầu), mùa ưa thích (mùa xuân, hè, thu, hay đông), và phái tính (nam hay nữ). Form sẽ 
cũng làm nổi bật một điều khiển Nút, mà khi được nhấn sẽ đặt thuộc tính Text của một trong số những điều 
khiển Label tới một chuỗi chứa tên người sử dụng, phái tính , và mùa yêu thích . Hình 15.4 cho thấy form cuối 
cùng của bạn sẽ xuất hiện như thế nào. 
 Hình 15.4: sự xuất hiện của form cuối 
Thực hiện những bước sau đây: 
1. Để tạo dự án mới, chọn File _ New Project trong VS .NET. Chọn Visual C# Projects trong vùng 
Project Types bên trái của hộp thoại New Project, và chọn ASP .NET Web Application trong vùng 
Templates (khuôn mẫu) bên phải. Nhập vào http: // Localhost/MyWeb- Application2 trong mục Location 
field. VS .NET sẽ hiển thị một form trống mà bạn có thể thêm những điều khiển vào. 
2. Bây giờ, thêm bốn điều khiển Label được liệt kê trong Bảng 15.2 vào form trống của bạn. Bảng này 
trình bày thuộc tính ID và Text để thiết đặt cho mỗi điều khiển Label của bạn. 
Bảng 15.2: những điều khiển Label 
Thuộc tính ID Thuộc tính Text 
HelloLabel Hello 
NameLabel Enter your name 
SeasonLabel Favorite season 
SexLabel Sex 
3. Tiếp theo, thêm một điều khiển TextBox vào bên phải NameLabel. Đặt thuộc tính ID cho điều khiển 
TextBox của bạn là NameTextBox. Người sử dụng sẽ nhập vào tên của họ ở NameTextBox khi form 
chạy. 
4. Chúng tôi muốn người sử dụng phải nhập vào tên của họ; nếu họ không nhập vào, chúng tôi muốn 
trình bày một thông báo nhắc họ thực hiện. Đạt được điều này, bạn sử dụng một điều khiển 
RequiredFieldValidator. Thêm một điều khiển RequiredFieldValidator vào dưới NameTextBox. Đặt 
thuộc tính ID cho điều khiển Required-FieldValidator của bạn tới NameRequiredFieldValidator. Đặt 
thuộc tính Text là " Bạn phải nhập vào tên của bạn! " . cuối cùng gán thuộc tính ControlToValidate đến 
NameTextBox. 
5. Tiếp theo, thêm một điều khiển RadioButtonList vào bên phải của SeasonLabel. Người sử dụng sẽ 
chọn mùa ưa thích của họ từ điều khiển này. Đặt thuộc tính ID cho điều khiển RadioButtonList của bạn 
tới SeasonRadioButtonList. Để thêm những nút rađiô tới SeasonRadioButtonList, Kích nút những dấu 
chấm (...) trong thuộc tính Items. Việc này sẽ hiễn thị ListItem Collection Editor, mà bạn thường dùng để 
thêm, điều chỉnh, hay loại bỏ những tiết mục (Items) trong những Tập hợp tiết mục (Items) cho điều 
khiển. Khi chạy, bất kỳ tiết mục nào bạn thêm vào tập hợp sẽ được trình bày như những nút rađiô. 
Hình 15.5 cho thấy cửa sổ ListItem Collection Editor với những mục được yêu cầu nhập vào cho form của bạn. 
 Hình 15.5: Bộ biên tập tập hợp ListItem 
6. Thuộc tính Selected cho biết liệu tiết mục có phải được lựa chọn đầu tiên trong form đang chạy. Thuộc 
tính Text chứa văn bản được trình bày cho tiết mục. Thuộc tính Value là giá trị được trả về khi tiết mục 
được chọn. 
7. Bây giờ kích nút Add để thêm tiết mục đầu tiên vào điều khiển RadioButtonList của bạn. Đặt thuộc 
tính Selected cho tiết mục tới true _ điều này gây cho nút rađiô sẽ thoạt tiên được chọn. Đặt thuộc tính 
Text cho tiết mục là Spring; đây là văn bản được trình bày cho nút rađiô. Đặt thuộc tính Value tới 0; đây 
là giá trị thực được lựa chọn. Bảng 15.3 cho thấy thưộc tính Selected, Text, và Value cho nút rađiô này, 
cùng với ba nút rađiô khác để thêm vào điều khiển RadioButtonList của bạn. 
Bảng 15.3: những tiết mục RadioButtonList 
Thuộc tính Selected Thuộc tính Text Thuộc tính Value 
True Spring 0 
False Summer 1 
False Fall 2 
False Winter 3 
8. Tiếp theo, thêm một điều khiển DropDownList vào form của bạn. Điều khiển này sẽ cho phép một 
người sử dụng chọn phái tính của họ (nam hay nữ). Đặt thuộc tính ID cho điều khiển DropDownList của 
bạn tới SexDropDown-List. Bạn thêm những tiết mục vào một điều khiển DropDownList sử dụng 
ListItem Collection Editor, mà Bạn truy cập sử dụng nút (…) thông qua thuộc tính Items. Mở ListItem 
Collection Editor và thêm những tiết mục trình bày trong Bảng 15.4. 
 Bảng 15.4: những tiết mục DropDownList 
 Thuộc tính Selected Thuộc tính Text Thuộc tính Value 
True Male 0 
False Female 1 
9. Cuối cùng, thêm một điều khiển Button vào form của bạn. Đặt thuộc tính ID cho điều khiển Button của 
bạn tới OkButton, Và Đặt thuộc tính Text tới Ok. Nhấn đúp OkButton để soạn thảo mã cho phương thức 
OkButton_Click(), và thêm những dòng mã sau đây vào phương thức này: 
HelloLabel.Text = 
 "Hello "+ NameTextBox.Text + 
 ", you are "+ SexDropDownList.SelectedItem.Text + 
 "and your favorite season is " + 
 SeasonRadioButtonList.SelectedItem.Text; 
Như bạn có thể nhìn thấy, hàng này đặt thuộc tính Text cho điều khiển HelloLabel tới một chuỗi chứa những 
mục nhập vào của người sử dụng trong NameTextBox, SexDropDownList, và những điều khiển 
SeasonRadioButton. 
Chạy form đã hoàn tất của bạn bởi nhấn Ctrl+ F5. Nhấn nút Ok mà không nhập vào một tên, và bạn sẽ thấy 
thông báo " Bạn phải nhập vào tên của bạn!", như được trình bày trong Hình 15.6 .Thông báo này đến từ điều 
khiển NameRequiredFieldValidator. 
 Hình 15.6: Thông báo từ điều khiển ameRequired-FieldValidator 
Khi bạn kết thúc chạy form của bạn, đóng nó và sự trở lại cửa sổ tiết kế form VS .NET. Bạn có thể xem HTML 
chứa những nhãn ASP.NET cho form của bạn bởi việc kích mối liên kết HTML tại đáy của cửa sổ tiết kế form. 
Kích mối liên kết HTML để xem mã cho form của bạn. Danh sách 15.3 trình bày file WebForm1.aspx cho form. 
Bạn sẽ lưu ý file này chứa nhiều điều khiển khác nhau được thêm vào form. 
Danh sách 15.3: Filee WebForm1.aspx 
<%@ Page language="c#" Codebehind="WebForm1.aspx.cs" 
 AutoEventWireup="false" 
 Inherits="WebApplication2.WebForm1" %> 
 WebForm1 
 <meta name="vs_targetSchema" 
 content=""> 
 <asp:Label id="HelloLabel" style="Z-INDEX: 101; LEFT: 17px; 
 POSITION: absolute; TOP: 16px" runat="server" 
 Width="322px" Height="23px">Hello 
 <asp:Label id="NameLabel" style="Z-INDEX: 102; LEFT: 17px; 
 POSITION: absolute; TOP: 54px" runat="server" 
 Width="114px" Height="22px">Enter your name 
 <asp:Label id="SeasonLabel" style="Z-INDEX: 103; LEFT: 17px; 
 POSITION: absolute; TOP: 107px" runat="server" 
 Width="101px" Height="32px">Favorite season 
 <asp:Label id="SexLabel" style="Z-INDEX: 104; LEFT: 17px; 
 POSITION: absolute; TOP: 221px" runat="server" 
 Width="33px" Height="15px">Sex 
 <asp:TextBox id="NameTextBox" style="Z-INDEX: 105; LEFT: 130px; 
 POSITION: absolute; TOP: 51px" runat="server" 
 Width="135px" Height="30px"> 
 <asp:RequiredFieldValidator id="NameRequiredFieldValidator" 
 style="Z-INDEX: 106; LEFT: 130px; POSITION: absolute; 
 TOP: 84px" runat="server" ErrorMessage="RequiredFieldValidator" 
 ControlToValidate="NameTextBox">You must enter your name! 
 <asp:RadioButtonList id="SeasonRadioButtonList" 
 style="Z-INDEX: 107; LEFT: 130px; POSITION: absolute; 
 TOP: 107px" runat="server" Width="152px" Height="107px"> 
 Spring 
 Summer 
 Fall 
 Winter 
 <asp:DropDownList id="SexDropDownList" style="Z-INDEX: 108; 
 LEFT: 130px; POSITION: absolute; TOP: 220px" runat="server" 
 Width="90px" Height="27px"> 
 Male 
 Female 
 <asp:Button id="OkButton" style="Z-INDEX: 109; LEFT: 17px; 
 POSITION: absolute; TOP: 261px" runat="server" 
 Width="83px" Height="27px" Text="Ok"> 
File WebForm1.aspx.cs chứa đựng mã đằng sau form của bạn. Bạn có thể xem mã này bởi việc chọn 
View ¾ Code, hay Bạn có thể nhấn F7 trên bàn phím. 
Sử dụng một điều khiển DataGrid để truy cập một Cơ sở dữ liệu 
Một DataGrid cho phép bạn truy cập những hàng trong một bảng cơ sở dữ liệu. Trong những mục sau đây, bạn 
sẽ học cách tạo ra một ứng dụng web ASP.NET sử dụng một điều khiển DataGrid để truy cập những hàng trong 
một bảng cơ sở dữ liệu. DataGrid bạn tạo ra sẽ trình bày những hàng từ những bảng Products của cơ sở dữ liệu 
Northwind. 
Tạo một ứng dụng Web 
Thực hiện những bước sau đây: 
1. Để tạo dự án mới, chọn File ¾ New Projects trong VS .NET. Chọn Visual C# Projects từ vùng 
Project Types ở bên trái trên hộp thoại New Project, và chọn ASP.NET Web Application từ vùng 
Templates bên phải. nhập vào http: // Localhost/ DataGrid- WebApplication trong mục Location 
field. Kích OK để tiếp tục. Dự án mới của bạn sẽ suất hiện một form trống. 
2. Tiếp theo, bạn thêm một điều khiển DataGrid vào form của bạn. Để làm điều này, chọn DataGrid 
từ Toolbox và kéo vào form của bạn. Hình 15.7 cho thấy form với DataGrid. 
 Hình 15.7: Form với một DataGrid 
3. Tiếp theo, bạn sẽ thêm một đối tượng SqlConnection và một đối tượng SqlDataAdapter vào form của 
bạn. Để thêm những đối tượng này, lựa chọn bảng Products trong Server Explorer và kéo nó tới form 
của bạn. (Việc thêm một đối tượng SqlConnection vào một form được bàn luận TrongChương 6, 
"Giới thiệu những ứng dụng Windows và ADO.NET, " và trong Chương 7, "Nối kết tới một Cơ sở dữ 
liệu.") 
 Ghi chú : Để hiển thị Server Explorer,chọn View ¾ Server Explorer, hay nhấn Ctrl+Alt+S 
trên bàn phím. 
4. Sau khi bạn kéo bảng Products tới form của bạn, VS.NET tạo ra một đối tượng SqlConnection đặt tên 
sqlConnection1 và một đối tượng SqlDataAdapter có tên sqlDataAdapter1. Kích đối tượng 
sqlConnection1 của bạn để trình bày những thuộc tính cho đối tượng này trong cửa sổ Properties. Để 
cho phép sqlConnection1 truy cấp cơ sở dữ liệu bạn cần đặt mật khẩu cho kết nối. Để làm điều này, 
bạn cần thêm một chuỗi con chứa pwd vào thuộc tính ConnectionString của sqlConnection1. Thêm 
pwd= sa; tới thuộc tính ConnectionString. 
 Ghi chú: Nếu bạn không có mật khẩu cho người sử dụng sa, bạn sẽ cần lấy nó từ người quản trị 
cơ sở dữ liệu của bạn. 
5. Tiếp theo, bạn sẽ sửa đổi phát biểu SELECT SQL dùng để truy xuất những hàng từ bảng Product. Kích 
đối tượng sqlDataAdapter1 để trình bày những thuộc tính cho đối tượng này. Kích biểu tượng 
addition ở bên trái của thuộc tính SelectCommand để hiển thị những thuộc tính động (dynamic 
properties). Một trong số những thuộc tính động là thuộc tính CommandText, chứa phát biểu 
SELECT. 
6. Kích CommandText và sau đó Kích nút (...) để trình bày Bộ tạo dựng truy vấn (Query Builder). Bạn sử 
dụng Query Builder để định nghĩa những câu lệnh SQL. Bạn có thể nhập câu lệnh SQL, hay Bạn có 
thể tạo nó cách trực quan. Bỏ chọn tất cả những cột ngoại trừ những cột sau: ProductID, 
ProductName, QuantityPerUnit, and UnitPrice. Điều này dẫn đến kết quả phát biểu SELECT SQL 
được thiết lập như sau: 
SELECT ProductID, ProductName, QuantityPerUnit, UnitPrice 
FROM Products 
7. Kích nút Ok để lưu phát biểu SELECT của bạn và đóng Bộ tạo dựng truy vấn. 
Tiếp theo, bạn cần tạo một đối tượng Dataset. Bạn sử dụng một đối tượng Dataset để cất giữ một bản sao cục bộ 
của thông tin được cất giữ trong cơ sở dữ liệu. Một đối tượng Dataset có thể đại diện cho những cấu trúc cơ sở 
dữ liệu như những bảng, những hàng và những cột. Trong ví dụ trong mục này, bạn sẽ sử dụng một đối tượng 
Dataset để cất giữ những hàng từ bảng Products. 
1. Kích một vùng trên form của bạn bên ngoài DataGrid. Tiếp theo, kích mối liên kết Generate Dataset 
(Phát sinh Dataset) gần đáy của cửa sổ thuộc tính. sẽ hiển thị hộp thoại Generate Dataset . Lựa chọn 
nút rađiô mới và chắc chắn rằng trường Text bên phải của nút rađiô này chứa DataSet1. Cũng, chắc 
chắn là hộp kiểm " Add This Dataset To The Designer" được chọn. Kích nút Ok để tiếp tục. Điều này 
thêm một đối tượng Dataset mới có tên dataSet11 vào form của bạn. 
2. Tiếp theo, bạn sẽ cần đặt thuộc tính DataSource của DataGrid tới đối tượng Dataset của bạn. Điều này 
gán nguồn dữ liệu cho DataGrid và cho phép những hàng từ Dataset được trình bày trong DataGrid 
của bạn. Để đặt thuộc tính DataSource, kích đối tượng DataGrid của bạn và thuộc tính DataSource 
được gán tới dataSet11. Đồng thời, đặt thuộc tính DataMember tới Products; đây chính là bảng với 
những hàng sẽ được trình bày bởi DataGrid của bạn. 
3. Tiếp theo, bạn sẽ cần thêm mã để cư trú sqlDataAdapter1 với những hàng được truy xuất bởi phát biểu 
SELECT. Điển hình, tốt nhất là đặt mã này trong phương thức Page_Load() của form của bạn. 
phương thức Page_Load() được gọi khi trang Web chứa form của bạn tại thời điểm thoạt tiên được tải 
hay khi được làm tươi lại (refresh). Thuộc tính IsPostBack của một trang là false khi trang được tải 
lần đầu tiên, và chuyển thành true khi nút submit (đệ trình) của một form được nhấn . Về sự thực hiện, 
nói chung bạn sẽ muốn truy xuất những hàng chỉ khi thuộc tính IsPostBack là false; nếu không bạn có 
lẽ đã không cần thiết phải tải lại những hàng từ cơ sở dữ liệu. Để xem mã của form của bạn, bạn chọn 
View - Code hay nhấn F7 trên bàn phím . viết mã cho phương thức Page_Load() như dưới đây: 
private void Page_Load(object sender, System.EventArgs e) 
{ 
 // Put user code to initialize the page here 
 if (!this.IsPostBack) 
 { 
 sqlDataAdapter1.Fill(dataSet11, "Products"); 
 this.DataBind(); 
 } 
} 
Phương thức Fill() truy xuất những hàng từ bảng Products và cư trú dataSet11 với những hàng đó.Rồi phương 
thức DataBind() điền đầy DataTable Products vào dataSet11 với những hàng được truy xuất từ bảng Products. 
Điều này gây ra những hàng sẽ được hiển thị trong DataGrid của form của bạn. 
Để chạy form của bạn, chọn Debug _ Start Without Debugging, hay nhấn Ctl+ F5 trên bàn phím ( xem Hình 
15.8). 
 Hình 15.8: form đang chạy 
Như bạn có thể thấy, một dải cuộn dọc được hiển thị để đáp ứng số lượng lớn những hàng truy xuất được từ 
bảng Product. Trong mục kế tiếp, bạn sẽ học cách tùy biến DataGrid . Bạn học cách kiểm soát số lượng hàng 
được trình bày trong DataGrid của bạn để không xuất hiện dải cuộn như thế nào, cũng như kiểm soát những khía 
cạnh khác của DataGrid . 
Tùy biến DataGrid 
Bạn tùy biến DataGrid của bạn bằng cách- đầu tiên chọn điều khiển DataGrid và sau đó kích mối liên kết 
Property Builder (bộ tạo dựng Thuộc tính ) ở đáy của cửa sổ Thuộc tính. Điều này hiển thị hộp thoại những 
thuộc tính cho DataGrid của bạn. Hộp thoại những thuộc tính được chia ra trong lăm vùng: General, Columns, 
Paging, Format, and Borders (tổng quan, những cột, sự phân trang, định dạng, và những viền bao). 
 Những thuộc tính Chung (general) 
Bạn sử dụng những thuộc tính chung để đặt nguồn dữ liệu cho DataGrid của bạn và sác định có hiển thị một 
đầu trang và phần cuối trang không, và một số những thuộc tính khác . Đặt những thuộc tính chung của bạn 
như trình bày trong Hình 15.9. 
 Hình 15.9: những thuộc tính Chung 
Những thuộc tính chung như sau: 
DataSource: là nguồn dữ liệu cho DataGrid của bạn. Trong ví dụ này, DataSource là dataSet11. 
DataMember :là tên của bảng mà DataGrid của bạn kết buộc tới. Trong ví dụ này, DataMember là 
Products. 
Data Key Field : Trường khóa Dữ liệu là tên của một cột hay biểu thức liên kết với mỗi hàng trong 
DataGrid của các bạn nhưng không được hiện thị. Bạn điển hình sử dụng nó để chỉ định khóa chính. 
Header and Footer : Đầu trang trình bày tên của những cột tại đỉnh của DataGrid. chọn Show Header và 
Show Footer. 
Behavior: (hành vi) Bạn có thể sắp xếp những cột trong đầu trang của DataGrid của bạn. Chọn Allow 
Sorting như thế những cột của bạn có thể được sắp xếp. 
Những thuộc tính cột (Columns properties) 
Bạn sử dụng những thuộc tính những cột để chọn những cột sẽ được trình bày trong DataGrid của bạn , và văn 
bản đầu trang và cuối trang sẽ được trình bày cho mỗi cột, và một số những thuộc tính khác. Kích mối liên kết 
Columns (những cột) của hộp thoại Properties và gán những thuộc tính những cột của bạn như trình bày trong 
Hình 15.10. 
 Hình 15.10: những thuộc tính những cột 
Những thuộc tính những cột như sau: 
Create Columns Automatically At Run Time : Hộp kiểm "Tự động tạo ra những cột trong thời gian chạy" chỉ 
định liệu có tự động tạo ra bao gồm tất cả những cột cho Dataset trong DataGrid của bạn khộng. Khi hộp kiểm 
này là unselected, Bạn có thể gán những thuộc tính khác cho mỗi cột theo một cách riêng. Không nên chọn hộp 
kiểm này. 
Column List : Danh sách Cột cho phép bạn chọn những cột từ Dataset của bạn để hiển thị trong DataGrid của 
bạn. Bạn chọn những cột từ vùng Available Columns (cột sẵn có bên trái) và thêm chúng vào vùng Selected 
Columns (những cột được chọn) ở bên phải sử dụng nút có mũi tên hướng phải. Chọn (All Fields) từ vùng 
Available Columns, và thêm chúng vào vùng Selected Columns. 
BoundColumn Properties : những thuộc tính BoundColumn cho phép bạn gán những thuộc tính cho mỗi cột. 
Bạn chọn cột bạn muốn đặt trong vùng Selected Columns , và sau đó gán những thuộc tính cho cột này. Những 
trường bạn có thể gán cho mỗi cột như sau: 
Header Text : Văn bản bạn muốn trình bày ở đầu trang cho một cột. 
Footer Text : Văn bản bạn muốn trình bày ở cuối trang cho một cột. 
Header Image : Hình ảnh mà bạn muốn trình bày ở đầu trang cho một cột. 
Sort Expression : cột hay biểu thức mà bạn muốn dùng để phân loại hay sắp xếp cột . UnitPrice được 
chọn như biểu thức phân loại. 
Data Field : tên của cột. 
Data Formatting Expression : Biểu thức định dạng dữ liệu cho phép bạn Định dạng một giá trị cột. 
Bạn có thể sử dụng một biểu thức định dạng để định dạng những ngày tháng và những số, và những thứ 
khác. Chẳng hạn, { 0: $##. 00} định dạng một số, thêm một dấu đô la đằng trước, và trình bày hai chữ 
số sau dấu phẩy ở số thập phân; Ví dụ, 19 được định dạng như $ 19.00. Biểu thức định dạng được đặt 
cho cột UnitPrice là { 0: $##. 00}. 
Những thuộc tính phân trang 
Tiếp theo, kích trên mối liên kết phân trang (Paging ) của hộp thoại Properties. Bình thường, tất cả những hàng 
được truy xuất bởi một phát biểu SELECT được trình bày trên một trang đơn cho DataGrid. Bạn có thể sử dụng 
những thuộc tính phân trang để tách tất cả những hàng vào những trang riêng biệt, với một số lượng hàng cố 
định trên mỗi trang trong DataGrid của bạn.Và rồi Bạn có thể chọn những nút để định hướng giữa những trang 
của những hàng này. Bạn sẽ đặt kích thước trang của bạn là năm hàng với nút Next và Previous để định hướng 
giữa những trang của những hàng. Đặt những thuộc tính Phân trang (Paging) của bạn như hình 15.11. 
 Hình 15.11: những thuộc tính Phân trang 
Những thuộc tính Phân trang như sau: 
Allow Paging : cho biết liệu sự phân trang được cho phép hay không. chọn kiểm hộp kiểm Allow 
Paging (cho phép phân trang). 
Page Size : điều khiển số hàng được trình bày trên mỗi trang. Đặt Page Size là 5. 
Show Navigation Buttons : hộp kiểm "hiển thị những nút dẫn hướng" điều khiển liệu những nút dẫn 
hướng có được hiển thị hay không. Những nút này cho phép bạn định hướng giữa những trang của 
những hàng. chôn hộp kiểm "hiển thị những nút dẫn hướng". 
Position : cho phép bạn đặt vị trí của những nút dẫn hướng . Đặt vị trí là Bottom. 
Mode : điều khiển kiểu của những nút dẫn hướng được trình bày. Bạn có thể sử dụng những nút Next 
và Previous hay page numbers để định hướng giữa những trang. Đặt Mode tới Next, Previous 
Buttons.. 
Next Page Button Text : thiết đặt văn bản hiển thị trên Nút Next page (trang kế tiếp). Để nguyên như 
& gt; như thế một ký tự lớn hơn (>) được trình bày. 
Previous Page Button Text : Văn bản trình bày trên "nút trang trước". Để nguyên là & lt; như thế 
một ký tự nhỏ hơn (<) được trình bày. 
Numeric Buttons : điều khiển những Số trình bày cho mỗi trang khi bạn đặt Mode to Page Numbers. 
thí dụ như, 1 dẫn hướng tới trang đầu tiên , 2 dẫn hướng tới trang thứ hai , vân vân. 
Ngoài việc cho phép sự phân trang bạn sẽ cũng cần thêm mã nào đó vào DataGrid của bạn để làm công việc dẫn 
đường, và bạn sẽ làm điều này không lâu sau đây. 
Những thuộc tính định dạng 
Tiếp theo, kích mối liên kết Format link (định dạng) của hộp thoại những thuộc tính. Bạn sử dụng những thuộc 
tính định dạng để kiểm soát sự xuất hiện của mỗi phần tử trên DataGrid của bạn . Bạn có thể đặt những đặc tính 
như màu của DataGrid của bạn, hoặc font chữ. Bạn cũng có thể đặt những thuộc tính hiển thị (display) của mỗi 
cột. Bạn sẽ đặt màu nền và màu chữ trắng hay đen, tương ứng. Bạn sẽ cũng đặt phông của văn bản được trình 
bày trong DataGrid của các bạn là Arial. Đặt những thuộc tính định dạng của bạn như trình bày trong Hình 15.12. 
 Hình 15.12: những thuộc tính định dạng 
Những thuộc tính định dạng như sau: 
Forecolor: tùy chọn Forecolor chỉ rõ màu văn bản . Đặt Forecolor tới màu Đen. 
Back Color: tùy chọn màu nền chỉ rõ màu nền đằng sau văn bản. Đặt màu nền tới màu trắng (White). 
Font Name : Tùy chọn tên phông chữ chỉ rõ Phông để trình bày văn bản. Đặt tên phông tới Arial. 
Font Size: tùy chọn kích thước phông kiểm soát kích thước của phông chữ được sử dụng để trình bày 
văn bản. 
Bold, Italic, Underline, Strikeout, Overline : những tùy chọn in đậm, chữ nghiêng, gạch dưới, vạch 
ngang giữa chữ, và đường trên - kiểm soát sự định dạng của ký tự cho văn bản. 
Horizontal Alignment : Tùy chọn sắp thành hàng nằm ngang chỉ rõ vị trí của văn bản trong ô. 
Những thuộc tính những viền bao 
Tiếp theo, kích vào mối liên kết viền bao (Borders) của hộp thoại những thuộc tính. Bạn sử dụng Borders 
properties để kiểm soát sự lót, khoảng cách và kiểu hiển thị của những lưới trong DataGrid của bạn. Bạn sẽ đặt 
màu viền của những hàng lưới trong DataGrid của các bạn tới màu xanh. Gán những thuộc tính những đường 
viền của bạn như trong Hình 15.13. 
 Hình 15.13: những thuộc tính những viền 
Những thuộc tính những viền như sau: 
Cell Padding : Kiểm soát lượng không gian (theo những điểm) giữa mép của một ô và những nội dung 
ô chứa trong DataGrid của bạn. 
Cell Spacing :kiểm soát lượng khoảng cách (theo những điểm) giữa mỗi phần tử trong DataGrid của 
bạn. 
Grid Lines :chỉ rõ hướng của những đường lưới trong Datagrid của bạn. 
Border Color :chỉ rõ màu của những đường lưới trong DataGrid của bạn. gán nó tới màu xanh. 
Border Width :điều chỉnh bề rộng viền và những đơn vị của lưới kẻ trong DataGrid của bạn. 
Một khi bạn đã hoàn tất việc gán những thuộc tính, kích nút Ok để tiếp tục. Tiếp theo, bạn sẽ viết mã Bộ xử lý sự 
kiện PageIndexChanged() để cho phép sự định hướng của những hàng trong DataGrid của bạn. 
Viết mã cho Bộ xử lý sự kiện PageIndexChanged() 
Như đã được đề cập trước đó, ngoài việc cho phép sự phân trang trong cửa sổ những thuộc tính phân trang, bạn 
sẽ cũng cần thêm mã nào đó tới DataGrid của bạn, Đặc biệt, tới phương thức xử lý sự kiện PageIndexChanged(). 
Phương thức này được gọi bất cứ khi nào bạn thay đổi trang trong DataGrid trong trang Web đang chạy của bạn. 
Trước khi bạn thêm mã cần thiết, đầu tiên bạn chọn DataGrid của bạn, sau đó bạn kích nút Events (sự kiện) 
trong cửa sổ những thuộc tính để hiển thị những sự kiện DataGrid cho bạn, xem Hình 15.14. 
 Hình 15.14: trình bày những sự kiện DataGrid 
Nhấn đúp sự kiện PageIndexChanged và gán phương thức DataGrid1_PageIndexChanged() như sau: 
private void DataGrid1_PageIndexChanged( 
 object source, 
 System.Web.UI.WebControls.DataGridPageChangedEventArgs e) 
{ 
 DataGrid1.CurrentPageIndex = e.NewPageIndex; 
 sqlDataAdapter1.Fill(dataSet11, "Products"); 
 DataGrid1.DataBind(); 
} 
Phát biểu đầu tiên bên trong thân phương thức như sau: 
DataGrid1.CurrentPageIndex = e.NewPageIndex; 
Phát biểu này gán trang hiện thời được hiển thị trong DataGrid1 tới trang mới được chọn sử dụng những nút dẫn 
hướng trong form đang chạy. Bạn gán trang hiện thời cho DataGrid1 sử dụng thuộc tính CurrentPageIndex, và 
Bạn lấy trang mới từ thuộc tính NewPageIndex của đối tượng DataGridPageChangedEventArgs. Bằng cách thiết 
đặt DataGrid1. CurrentPageIndex bằng (equal to) e.NewPageIndex, Sự dẫn hướng tới trang mới của những hàng 
được thực hiện. 
Phát biểu thứ hai như sau: 
sqlDataAdapter1.Fill(dataSet11, "Products"); 
Phát biểu này gọi phương thức Fill() của sqlDataAdapter1 để cư trú dataSet11 với tập hợp của những hàng tiếp 
theo từ bảng Products. 
Phát biểu thứ ba như sau: 
DataGrid1.DataBind(); 
Phát biểu này gọi phương thức DataBind() của DataGrid1, kết quả tập hợp mới của những hàng sẽ được trình 
bày. 
Ghi chú 
Với VS .NET, bạn cũng có thể đi tới Code view và sự sử dụng những thực đơn thả xuống để tạo ra chữ 
ký cho những sự kiện. điều này ứng dụng với bất kỳ sự kiện nào mà bạn thêm vào. Tất nhiên, nhấn đúp 
vào những sự kiện để lấy sự kiện " mặc định " thì dễ dàng hơn, nhưng có những sự kiện khác cho mỗi 
điều khiển. 
Chạy form của bạn bởi việc nhấn Ctrl+ F5 trên bàn phím . Hình 15.15 cho thấy sự vận hành của fom. 
 Hình 15.15: form đang chạy 
Sử dụng những nút dẫn hướng để di chuyển giữa những trang của những hàng. Một khi bạn kết thúc việc chạy 
form của bạn, đóng nó và trở lại cửa sổ thiết kế form VS .NET. Kích mối liên kết HTML để xem mã của form 
của bạn. Danh sách 15.4 trình bày file WebForm1.aspx cho form. Bạn sẽ chú ý là file này có chứa một điều 
khiển DataGrid với những cột thích hợp. 
Danh sách 15.4:file WebForm1.aspx 
<%@ Page language="c#" Codebehind="WebForm1.aspx.cs" 
 AutoEventWireup="false" 
 Inherits="DataGridWebApplication.WebForm1" %> 
 WebForm1 
 <meta content="" 
 name="vs_targetSchema"> 
 <asp:datagrid id=DataGrid1 style="Z-INDEX: 101; LEFT: 16px; 
 POSITION: absolute; TOP: 11px" runat="server" 
 AutoGenerateColumns="False" BorderColor="Blue" Font-Bold="True" 
 Font-Names="Arial" ForeColor="Black" BackColor="White" 
 AllowPaging="True" PageSize="5" ShowFooter="True" 
 DataMember="Products" AllowSorting="True" 
 DataSource="" Height="333px" Width="352px"> 
 <asp:BoundColumn 
 DataField="ProductID" HeaderText="ProductID"> 
 <asp:BoundColumn DataField="ProductName" 
 HeaderText="ProductName"> 
 <asp:BoundColumn DataField="QuantityPerUnit" 
 HeaderText="QuantityPerUnit"> 
 <asp:BoundColumn DataField="UnitPrice" 
 SortExpression="UnitPrice" HeaderText="UnitPrice" 
 DataFormatString="{0:$##.00}"> 
Trong mục kế tiếp, bạn sẽ học cách sử dụng một điều khiển DataList để truy cập một cơ sở dữ liệu như thế nào. 
Sử dụng một điều khiển DataList để truy cập một Cơ sở dữ liệu 
Trong mục này bạn sẽ học cách sử dụng một điều khiển DataList để truy cập những hàng trong bảng Products. 
Mẹo nhỏ 
Một DataList cung cấp bạn khá nhiều tính linh hoạt trong việc trình bày những giá trị cột hơn là một 
DataGrid. 
Thực hiện những bước sau đây: 
1. Để tạo dự án mới, chọn File ¾ New Project trong VS .NET. Chọn Visual C# Projects từ vùng Project 
Types trên bên trái của hộp thoại New Project (dự án mới), và chọn ASP .NET Web Application từ 
vùng Templates (khung mẫu) bên phải. Nhập vào "http: // Localhost/ DataList- WebApplication" 
trong Location field (trường định vị). Kích OK để tiếp tục. Dự án mới của bạn sẽ chứa một form 
trống. 
2. Tiếp theo, bạn sẽ thêm một đối tượng SqlConnection và một đối tượng SqlDataAdapter vào form của 
bạn. Chọn bảng Products trong Server Explorer và kéo nó tới form của bạn. 
3. Sau khi bạn kéo bảng Products tới form của bạn, VS .NET tạo ra một đối tượng SqlConnection có tên 
sqlConnection1 và một đối tượng SqlDataAdapter có tên sqlDataAdapter1. 
4. Kích đối tượng sqlConnection1 của bạn để trình bày những thuộc tính cho đối tượng này trong cửa sổ 
những thuộc tính. Để sqlConnection1 có thể truy cập cơ sở dữ liệu, bạn cần đặt mật khẩu cho kết nối. 
Thêm pwd= sa; tới thuộc tính ConnectionString. 
5. Tiếp theo, bạn sẽ sửa đổi phát biểu SELECT _SQL dùng để truy xuất những hàng từ bảng Products. 
Kích đối tượng sqlDataAdapter1 của bạn để trình bày những thuộc tính cho đối tượng này. Kích biểu 
tượng addition ở bên trái thuộc tính SelectCommand để trình bày những thuộc tính động; một trong 
số những thuộc tính động là thuộc tính CommandText, chứa phát biểu SELECT. Tiếp theo, kích 
CommandText rồi sau đó kích nút ellipsis để hiển thị Query Builder. Bạn có thể nhập câu lệnh SQL, 
hay Bạn có thể xây dựng nó theo cách trực quan. Bỏ chọn tất cả những cột trừ ProductID, 
ProductName, Q
            Các file đính kèm theo tài liệu này:
 LapTrinhCoSoDuLieuVoi-CSharp_phan-3 68.pdf LapTrinhCoSoDuLieuVoi-CSharp_phan-3 68.pdf