lap trinhcosodulieuvoi c-sharp_phan-3

124
Phn 3: Lp trình Cơ sdliu nâng cao vi ADO.NET DANH SÁCH CÁC CHƯƠNG Chương 14: Điu khin Giao dch nâng cao Chương 15: Gii thiu nhng ng dng Web -ASP.NET Chương 16: Sdng htrXML ca SQL Server Chương 17: Nhng dch vMng Chương 14: Điu khin Giao dch nâng cao Tng quan Trong Chương 3 , "Gii thiu vngôn ngtruy vn có cu trúc, " Bn đã thy là bn có thnhóm nhng câu lnh SQL vào trong nhng giao dch như thế nào. Nhng câu lnh SQL này được coi như mt đơn vcông vic lôgíc. Mt ví dca điu này là mt chuyn đổi tin ttài khon này sang tài khon khác sdng hai phát biu UPDATE. Mt rút tin ra khi mt tài khon, và mt chuyn tin vào trong mt tài khon khác . Chai phát biu UPDATE có thđược xem như là mt giao dch đơn vì chai phát biu đều phi được giao phó hay phc nguyên cùng nhau, nếu không tin có thbmt. Nhng cơ sdliu hin đại có thxlý nhiu người sdng và nhng chương trình truy cp cơ sdliu đồng thi, mi chương trình chy tim tàng nhng giao dch ca mình trong cơ sdliu. Điu này được biết như nhng giao dch trùng hp bi vì hđược chy cùng lúc. Phn mm cơ sdliu phi có khnăng để tha mãn nhng nhu cu ca tt cnhng giao dch trùng hp này, cũng như bo trì stoàn vn ca nhng hàng được ct gitrong nhng bng cơ sdliu. Bn có thkim soát lượng cô lp tn ti gia nhng giao dch ca bn và nhng giao dch khác mà có lđang được chy trong cơ sdliu. Trong Chương 8 , "Thc hin nhng lnh Cơ sdliu, " Bn đã thy cách sdng mt giao dch vi mt đối tượng Lnh như thế nào. Trong Chương 11 , "Sdng nhng đối tượng Dataset để sa đổi Dliu, " Bn đã thy cách sdng mt giao dch vi mt DataAdapter như thế nào. Trong chương này, bn sđi sâu vào điu khin giao dch nâng cao sdng SQL Server và ADO.NET. Nhng mt ni bt trong Chương này: . Lp SqlTransaction . Nhng thuc tính giao dch ACID . SThiết đặt mt savepoint . Đặt mc cô lp giao dch . Hiu vnhng khóa SQL Server LP SqlTransaction: Có ba lp Giao dch SqlTransaction, OleDbTransaction, và OdbcTransaction. Bn sdng mt đối tượng Transaction để đại din cho mt giao dch cơ sdliu, và mt đối tượng ca lp SqlTransaction để đại din cho mt giao dch cơ sdliu trong mt cơ sdliu SQL Server. Bng 14.1 trình bày mt sthuc tính SqlTransaction, và Bng 14.2 cho thy mt snhng phương thc ca SqlTransaction. Bn sxem xét cách sdng mt sthuc tính và phương pháp trong chương này. Bng 14.1: nhng thuc tính SqlTransaction

Upload: hien-phung

Post on 09-Jun-2015

622 views

Category:

Documents


1 download

TRANSCRIPT

Page 1: Lap trinhcosodulieuvoi c-sharp_phan-3

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

Page 2: Lap trinhcosodulieuvoi c-sharp_phan-3

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.

Page 3: Lap trinhcosodulieuvoi c-sharp_phan-3

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

Page 4: Lap trinhcosodulieuvoi c-sharp_phan-3

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

Page 5: Lap trinhcosodulieuvoi c-sharp_phan-3

/* 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);

Page 6: Lap trinhcosodulieuvoi c-sharp_phan-3

// 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

Page 7: Lap trinhcosodulieuvoi c-sharp_phan-3

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.

Page 8: Lap trinhcosodulieuvoi c-sharp_phan-3

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 */

Page 9: Lap trinhcosodulieuvoi c-sharp_phan-3

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.

Page 10: Lap trinhcosodulieuvoi c-sharp_phan-3

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;

Page 11: Lap trinhcosodulieuvoi c-sharp_phan-3

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 "+

Page 12: Lap trinhcosodulieuvoi c-sharp_phan-3

"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

Page 13: Lap trinhcosodulieuvoi c-sharp_phan-3

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(); } }

Page 14: Lap trinhcosodulieuvoi c-sharp_phan-3

Đầ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

Page 15: Lap trinhcosodulieuvoi c-sharp_phan-3

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.

Page 16: Lap trinhcosodulieuvoi c-sharp_phan-3

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

Page 17: Lap trinhcosodulieuvoi c-sharp_phan-3

đổ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:

Page 18: Lap trinhcosodulieuvoi c-sharp_phan-3

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

Page 19: Lap trinhcosodulieuvoi c-sharp_phan-3

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

Page 20: Lap trinhcosodulieuvoi c-sharp_phan-3

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);

Page 21: Lap trinhcosodulieuvoi c-sharp_phan-3

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'

Page 22: Lap trinhcosodulieuvoi c-sharp_phan-3

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();

Page 23: Lap trinhcosodulieuvoi c-sharp_phan-3

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()

Page 24: Lap trinhcosodulieuvoi c-sharp_phan-3

{ // 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();

Page 25: Lap trinhcosodulieuvoi c-sharp_phan-3

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

Page 26: Lap trinhcosodulieuvoi c-sharp_phan-3

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:

Page 27: Lap trinhcosodulieuvoi c-sharp_phan-3

■ 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.

Page 28: Lap trinhcosodulieuvoi c-sharp_phan-3

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.

Page 29: Lap trinhcosodulieuvoi c-sharp_phan-3

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" %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" > <HTML> <HEAD> <title>WebForm1</title> <meta content="Microsoft Visual Studio 7.0" name="GENERATOR"> <meta content="C#" name="CODE_LANGUAGE"> <meta content="JavaScript" name="vs_defaultClientScript"> <meta content="http://schemas.microsoft.com/intellisense/ie5" name="vs_targetSchema"> </HEAD>

Page 30: Lap trinhcosodulieuvoi c-sharp_phan-3

<body MS_POSITIONING="GridLayout"> <form id="Form1" method="post" runat="server"> <asp:TextBox id="TextBox1" style="Z-INDEX: 101; LEFT: 13px; POSITION: absolute; TOP: 11px" runat="server" Width="386px" Height="212px" TextMode="MultiLine"></asp:TextBox> <asp:Button id="Button1" style="Z-INDEX: 102; LEFT: 17px; POSITION: absolute; TOP: 231px" runat="server" Width="82px" Height="22px" Text="Press Me!"></asp:Button> </form> </body> </HTML>

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.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" > <HTML> <HEAD> <title>WebForm1</title> <meta content="Microsoft Visual Studio 7.0" name="GENERATOR"> <meta content="C#" name="CODE_LANGUAGE"> <meta content="JavaScript" name="vs_defaultClientScript"> <meta content="http://schemas.microsoft.com/intellisense/ie5" name="vs_targetSchema"> </HEAD>

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:

<form id="Form1" method="post" runat="server">

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

Page 31: Lap trinhcosodulieuvoi c-sharp_phan-3

<asp:TextBox id="TextBox1" style="Z-INDEX: 101; LEFT: 13px; POSITION: absolute; TOP: 11px" runat="server" Width="386px" Height="212px" TextMode="MultiLine"></asp:TextBox>

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!"></asp:Button>

Những hàng còn lại trong file WebForm1.aspx kết thúc form, thân và file:

</form> </body> </HTML>

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> /// Summary description for WebForm1. /// </summary> 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) {

Page 32: Lap trinhcosodulieuvoi c-sharp_phan-3

// // CODEGEN: This call is required by the ASP.NET Web Form Designer. // InitializeComponent(); base.OnInit(e); } /// <summary> /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// </summary> 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

Page 33: Lap trinhcosodulieuvoi c-sharp_phan-3

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

Page 34: Lap trinhcosodulieuvoi c-sharp_phan-3

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.

Page 35: Lap trinhcosodulieuvoi c-sharp_phan-3

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

Page 36: Lap trinhcosodulieuvoi c-sharp_phan-3

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

Page 37: Lap trinhcosodulieuvoi c-sharp_phan-3

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" %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" > <HTML> <HEAD> <title>WebForm1</title> <meta name="GENERATOR" Content="Microsoft Visual Studio 7.0"> <meta name="CODE_LANGUAGE" Content="C#">

Page 38: Lap trinhcosodulieuvoi c-sharp_phan-3

<meta name="vs_defaultClientScript" content="JavaScript"> <meta name="vs_targetSchema" content="http://schemas.microsoft.com/intellisense/ie5"> </HEAD> <body MS_POSITIONING="GridLayout"> <form id="Form1" method="post" runat="server"> <asp:Label id="HelloLabel" style="Z-INDEX: 101; LEFT: 17px; POSITION: absolute; TOP: 16px" runat="server" Width="322px" Height="23px">Hello</asp:Label> <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> <asp:Label id="SeasonLabel" style="Z-INDEX: 103; LEFT: 17px; POSITION: absolute; TOP: 107px" runat="server" Width="101px" Height="32px">Favorite season</asp:Label> <asp:Label id="SexLabel" style="Z-INDEX: 104; LEFT: 17px; POSITION: absolute; TOP: 221px" runat="server" Width="33px" Height="15px">Sex</asp:Label> <asp:TextBox id="NameTextBox" style="Z-INDEX: 105; LEFT: 130px; POSITION: absolute; TOP: 51px" runat="server" Width="135px" Height="30px"></asp:TextBox> <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:RequiredFieldValidator> <asp:RadioButtonList id="SeasonRadioButtonList" style="Z-INDEX: 107; LEFT: 130px; POSITION: absolute; TOP: 107px" runat="server" Width="152px" Height="107px"> <asp:ListItem Value="0" Selected="True">Spring</asp:ListItem> <asp:ListItem Value="1">Summer</asp:ListItem> <asp:ListItem Value="2">Fall</asp:ListItem> <asp:ListItem Value="3">Winter</asp:ListItem> </asp:RadioButtonList> <asp:DropDownList id="SexDropDownList" style="Z-INDEX: 108; LEFT: 130px; POSITION: absolute; TOP: 220px" runat="server" Width="90px" Height="27px"> <asp:ListItem Value="0" Selected="True">Male</asp:ListItem> <asp:ListItem Value="1">Female</asp:ListItem> </asp:DropDownList> <asp:Button id="OkButton" style="Z-INDEX: 109; LEFT: 17px; POSITION: absolute; TOP: 261px" runat="server" Width="83px" Height="27px" Text="Ok"></asp:Button> </form> </body> </HTML>

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

Page 39: Lap trinhcosodulieuvoi c-sharp_phan-3

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

Page 40: Lap trinhcosodulieuvoi c-sharp_phan-3

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).

Page 41: Lap trinhcosodulieuvoi c-sharp_phan-3

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.

Page 42: Lap trinhcosodulieuvoi c-sharp_phan-3

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.

Page 43: Lap trinhcosodulieuvoi c-sharp_phan-3

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}.

Page 44: Lap trinhcosodulieuvoi c-sharp_phan-3

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.

Page 45: Lap trinhcosodulieuvoi c-sharp_phan-3

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.

Page 46: Lap trinhcosodulieuvoi c-sharp_phan-3

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.

Page 47: Lap trinhcosodulieuvoi c-sharp_phan-3

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:

Page 48: Lap trinhcosodulieuvoi c-sharp_phan-3

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" %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" > <HTML> <HEAD> <title>WebForm1</title> <meta content="Microsoft Visual Studio 7.0" name="GENERATOR"> <meta content="C#" name="CODE_LANGUAGE"> <meta content="JavaScript" name="vs_defaultClientScript">

Page 49: Lap trinhcosodulieuvoi c-sharp_phan-3

<meta content="http://schemas.microsoft.com/intellisense/ie5" name="vs_targetSchema"> </HEAD> <body MS_POSITIONING="GridLayout"> <form id="Form1" method="post" runat="server"> <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="<%# dataSet11 %>" Height="333px" Width="352px"> <Columns> <asp:BoundColumn DataField="ProductID" HeaderText="ProductID"> </asp:BoundColumn> <asp:BoundColumn DataField="ProductName" HeaderText="ProductName"> </asp:BoundColumn> <asp:BoundColumn DataField="QuantityPerUnit" HeaderText="QuantityPerUnit"> </asp:BoundColumn> <asp:BoundColumn DataField="UnitPrice" SortExpression="UnitPrice" HeaderText="UnitPrice" DataFormatString="{0:$##.00}"> </asp:BoundColumn> </Columns> </asp:datagrid></form> </body> </HTML>

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

Page 50: Lap trinhcosodulieuvoi c-sharp_phan-3

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, QuantityPerUnit, and UnitPrice. Kết quả là trong phát biểu SELECT_ SQL sẽ được thiết lập như sau đây:

SELECT ProductID, ProductName, QuantityPerUnit, UnitPrice FROM Products

6. Kích OK để tiếp tục. 7. Tiếp theo, bạn cần tạo một đối tượng Dataset. Kích một vùng trên form của bạn. Tiếp theo, kích liên

kết Generate-Dataset ở đáy của cửa sổ những thuộc tính. điều này hiển thị hộp thoại Generate-Dataset (Phát sinh tập dữ liệu). Chọn nút "New radio " và chắc chắn rằng trường bên phải của nút radio này chứa DataSet1. 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.

8. Tiếp theo, bạn sẽ thêm một điều khiển DataList vào form của bạn. Để làm điều này, chọn DataList từ Toolbox và kéo nó đến form của bạn. Hình 15.16 cho thấy form với DataList mới.

Hình 15.16: Form với một DataList

9. Tiếp theo, bạn sẽ cần đặt thuộc tính DataSource của DataList của bạn tới đối tượng Dataset của bạn được tạo ra trước đó. Điều này gán nguồn dữ liệu cho DataList của bạn và cho phép những hàng từ Dataset sẽ được trình bày trong DataList của bạn. Để gán thuộc tính DataSource, kích đối tượng DataList của bạn và gán thuộc tính DataSource tới dataSet11. Đồng thời, gán thuộc tính DataMember của DataList tới Products; đây là bảng với những hàng được trình bày bởi DataList.

Page 51: Lap trinhcosodulieuvoi c-sharp_phan-3

Một DataList sử dụng những khuôn mẫu mà định nghĩa nội dung của nó sẽ được hiển thị như thế nào, và nhiệm vụ kế tiếp của bạn là thiết lập những khuôn mẫu này.

Mẹo nhỏ: Đó là những khuôn mẫu DataList mà cho bạn tính linh hoạt cho sự sắp đặt những điều khiển trình bày những giá trị cột.

Bạn sẽ soạn thảo khuôn mẫu định nghĩa đầu mục và cuối mục cho DataList, cùng với khuôn mẫu định nghĩa những tiết mục thực tế được trình bày bên trong DataList của bạn:

1. Để soạn thảo khuôn mẫu đầu mục và cuối mục, nhấn phải DataList của bạn và chọn Edit Template Header And Footer Templates "Những khuôn mẫu đầu mục và cuối mục".

2. Bạn có thể thêm những điều khiển vào những vùng bên trong những vùng HeaderTemplate và

FooterTemplate. Bất kỳ điều khiển nào bạn thêm vào đều sẽ được trình bày tương ứng tại khởi đầu và kết thúc của DataList. Thêm một nhãn ở HeaderTemplate; bạn làm điều này bởi kéo một điều khiển nhãn từ Toolbox đến vùng trống ở dưới HeaderTemplate. Đặt thuộc tính Text cho nhãn này tới Products. Đồng thời, thêm một nhãn trong vùng FooterTemplate và gán thuộc tính Text của nó tới End of list. Hình 15.17 cho thấy những khuôn mẫu đầu mục và cuối mục được sửa đổi và những điều khiển Nhãn.

Hình dung 15.17: Những khuôn mẫu đầu mục và cuối mục được sửa đổi cùng với những điều khiển Nhãn

Ghi nhớ: Bạn có thể kết thúc sự soạn thảo một khuôn mẫu tại bất kỳ thời gian nào bởi việc nhấn phải DataList của bạn và chọn End Template Editing " kết thúc soạn thảo Khuôn mẫu ".

3. Tiếp theo, bạn sẽ soạn thảo khuôn mẫu “Item” (tiết mục) và thêm những điều khiển “Label” (nhãn ) để

hiển thị những cột ProductID, ProductName, QuantityPerUnit, và UnitPrice. Nhấn phải DataList của bạn và chọn Edit Template Item Templates. Hình 15.18 trình bày “the Item Templates editor” (bộ biên tập khuôn mẫu tiết mục) .

Page 52: Lap trinhcosodulieuvoi c-sharp_phan-3

Hình 15.18: Bộ biên tập khuôn mẫu Tiết mục Như bạn có thể thấy từ Hình 15.18, Bộ biên tập khuôn mẫu Tiết mục được chia vào trong bốn vùng sau đây:

ItemTemplate: chứa những điều khiển mà bạn điển hình thường dùng để trình bày những giá trị cột. AlternatingItemTemplate: chứa những điều khiển mà được hiển thị sau những điều khiển trong ItemTemplate. SelectedItemTemplate: chứa những điều khiển được hiện ra khi bạn chọn một tiết mục. EditItemTemplate: chứa những điều khiển mà được hiện ra khi bạn soạn thảo một tiết mục.

Bạn sẽ thêm một bảng vào vùng ItemTemplate, và sau đó Bạn sẽ thêm bốn điều khiển Label trong những ô của bảng của bạn. Bốn điều khiển Label sẽ trình bày những giá trị cho những cột ProductID, ProductName, QuantityPerUnit, và UnitPrice. Để thêm một bảng bạn thực hiện như sau:

1. Kích bất cứ nơi đâu trong vùng ItemTemplate và chọn Table > Insert Table. Gán những thuộc tính cho bảng như Hình 15.19.

Page 53: Lap trinhcosodulieuvoi c-sharp_phan-3

Hình 15.19: đặt những thuộc tính của bảng

2. Tiếp theo, kéo một Nhãn tới ô đầu tiên trong bảng. Bạn sẽ sử dụng Nhãn đầu tiên này để trình bày cột ProductID. Đặt thuộc tính ID của Nhãn của bạn tới ProductID, như trong Hình 15.20.

Hình 15.20: việc thêm Nhãn

3. Dùng Nhãn để trình bày cột ProductId, bạn sẽ cần kết buộc nhãn tới cột này. Để làm điều này, kích nút ellipsis (...) trong thuộc tính DataBindings. Bạn sẽ thấy hộp thoại DataBindings. Mở nút Container bởi kích biểu tượng addition , rồi mở nút DataItem; cuối cùng, chọn cột ProductID, như như trình bày trong Hình 15.21.

Page 54: Lap trinhcosodulieuvoi c-sharp_phan-3

Hình 15.21: Kết buộc Nhãn tới cột ProductID

1. Tiếp theo, thêm ba điều khiển Nhãn nữa vào trong những ô còn lại của bảng . Gán thuộc tính ID cho ba điều khiển Nhãn tới ProductName, QuantityPerUnit, và UnitPrice, tương ứng. Đồng thời, kết buộc toàn bộ những điều khiển Nhãn của bạn tới những cột ProductName, QuantityPerUnit, và UnitPrice, tương ứng.

Cảnh báo: khi bạn thêm những điều khiển Nhãn vào những ô, bạn chú ý là những ô còn lại sẽ co lại. Đề phòng điều này vì nó có thể làm cho việc thêm những điều khiển Nhãn khác một chút khó khăn.

5. Tiếp theo, bạn sẽ sửa đổi HTML cho form của bạn để làm bảng dễ đọc hơn . Bạn sẽ thay đổi những

thuộc tính chiều rộng (width) và viền (border) của thẻ Table và thiết đặt thuộc tính chiều rộng của những thẻ (tags) TD.

Ghi nhớ: thẻ Table định nghĩa một Bảng, và thẻ TD định nghĩa một phần tử trong một hàng.

6. Để nhìn mã HTML của form của các bạn, kích mối liên kết HTML bên dưới cửa sổ thiết kế form để

xem mã của form. Gán những thuộc tính chiều rộng và viền của thẻ Table của bạn tới 320 và 1, tương ứng, và gán những thuộc tính chiều rộng của bốn nhãn TD tới 20, 100, 100, và 100, tương ứng. HTML dưới đây cho thấy những sự thay đổi này

<TABLE id="Table5" cellSpacing="1" cellPadding="1" width="320" border="1"> <TR> <TD width="20"> <asp:Label id=ProductID runat="server" Text=' <%# DataBinder.Eval(Container, "DataItem.ProductID") %>'> </asp:Label></TD> <TD width="100"> <asp:Label id=ProductName runat="server" Text=' <%# DataBinder.Eval(Container, "DataItem.ProductName") %>'> </asp:Label></TD> <TD width="100"> <asp:Label id=QuantityPerUnit runat="server" Text=' <%# DataBinder.Eval(Container, "DataItem.QuantityPerUnit") %>'> </asp:Label></TD> <TD width="100">

Page 55: Lap trinhcosodulieuvoi c-sharp_phan-3

<asp:Label id=UnitPrice runat="server" Text=' <%# DataBinder.Eval(Container, "DataItem.UnitPrice") %>'> </asp:Label></TD> </TR> </TABLE>

Ghi nhớ: thuộc tính ID của thẻ Table của bạn có lẽ đã khác với mã được trình bày trong mả trước. Đừng bận tâm đến sự thay đổi thuộc tính ID cho thẻ Table của bạn.

7. 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 của bạn. Điển hình, sự sắp xếp 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 là khi trang Web chứa form của bạn thoạt tiên được tải (initially loaded) hay làm mới lại (refreshed). Mở mã cho form của bạn bởi chọn View > Code, hay nhấn F7 trên bàn phím. Gán phương thức Page_Load() như sau:

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ú đối tượng dataSet11 với những hàng đó. Rồi phương thức DataBind() sẽ trình bày những hàng trong DataList của form của bạn. Để chạy form của bạn, chọn Debug Start Without Debugging, hay nhấn Ctrl+ F5 trên bàn phím . Hình 15.22 cho thấy form đang chạy.

Hình 15.22: form đang chạy Một khi bạn kết thúc chạy form của bạn, đóng nó và trở lại cửa sổ thiết kế form. Kích mối liên kết HTML để

Page 56: Lap trinhcosodulieuvoi c-sharp_phan-3

xem mã của form . Danh sách 15.5 trình bày file WebForm1.aspx cho form. Bạn chú ý rằng file này chứa một điều khiển DataList với những cột thích hợp. Danh sách 15.5: file WebForm1.aspx

<%@ Page language="c#" Codebehind="WebForm1.aspx.cs" AutoEventWireup="false" Inherits="DataListWebApplication.WebForm1" %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" > <HTML> <HEAD> <title>WebForm1</title> <meta content="Microsoft Visual Studio 7.0" name="GENERATOR"> <meta content="C#" name="CODE_LANGUAGE"> <meta content="JavaScript" name="vs_defaultClientScript"> <meta content="http://schemas.microsoft.com/intellisense/ie5" name="vs_targetSchema"> </HEAD> <body MS_POSITIONING="GridLayout"> <form id="Form1" method="post" runat="server"> <asp:datalist id=DataList1 style="Z-INDEX: 101; LEFT: 33px; POSITION: absolute; TOP: 28px" runat="server" DataMember="Products" Height="140" Width="297" DataSource=" <%# dataSet11 %>"> <HeaderTemplate> <asp:Label id="Label1" runat="server">Products</asp:Label> </HeaderTemplate> <FooterTemplate> <asp:Label id="Label2" runat="server">End of list</asp:Label> </FooterTemplate> <ItemTemplate> <TABLE id="Table5" cellSpacing="1" cellPadding="1" width="320" border="1"> <TR> <TD width="20"> <asp:Label id=ProductID runat="server" Text=' <%# DataBinder.Eval(Container, "DataItem.ProductID") %>'> </asp:Label></TD> <TD width="100"> <asp:Label id=ProductName runat="server" Text=' <%# DataBinder.Eval(Container, "DataItem.ProductName") %>'> </asp:Label></TD> <TD width="100"> <asp:Label id=QuantityPerUnit runat="server" Text=' <%# DataBinder.Eval(Container, "DataItem.QuantityPerUnit") %>'> </asp:Label></TD> <TD width="100"> <asp:Label id=UnitPrice runat="server" Text=' <%# DataBinder.Eval(Container, "DataItem.UnitPrice") %>'> </asp:Label></TD> </TR> </TABLE> </ItemTemplate> </asp:datalist></form> </body> </HTML>

Page 57: Lap trinhcosodulieuvoi c-sharp_phan-3

Bảo trì trạng thái trong một ứng dụng Web Giao thức truyền tải siêu văn bản (HTTP) không duy trì trạng thái giữa những trang được cung cấp bởi máy chủ phục vụ mạng trong thời gian mỗi vòng truyền tải. Bất kỳ thông tin nào bạn cung cấp trong một form cho những phương tiện này - Bắt đầu khi bạn có một trang mới. Nếu bạn đơn giản đang nhận được những trang Web HTML tĩnh, thì đây không là một vấn đề. tuy nhiên ,nếu bạn đang đặt hàng một sản phẩm, thì máy chủ phục vụ cần nhớ những món gì mà bạn đã đặt. Để máy chủ phục vụ Mạng nhớ những gì bạn đã thực hiện trong vòng truyền tải sau cùng , bạn có thể lưu trữ thông tin trên máy chủ phục vụ hay trên máy tính khách mà bộ duyệt web đang tục chạy. Việc cất giữ thông tin trên máy khách có nghĩa là bạn không sử dụng bất kỳ tài nguyên nào trên máy chủ phục vụ để lưu trữ thông tin này, và trình ứng dụng Web của bạn có thể tiềm tàng xử lý nhiều người sử dụng hơn. Việc cất giữ thông tin trên máy chủ phục vụ cho bạn nhiều điều khiển của thông tin lưu trữ hơn, nhưng vì thế sẽ tiêu thụ những tài nguyên của máy chủ phục vụ, bạn cần cẩn thận không lưu trữ quá nhiều; nếu không ứng dụng web của bạn sẽ không có khả năng để xử lý nhiều người sử dụng.

Cất giữ Thông tin trên máy khách

Để cất giữ thông tin trên máy khách, bạn có thể sử dụng cookies hay thuộc tính ViewState của đối tượng Page (Trang). Chúng ta hãy xem xét cách sử dụng cookies và thuộc tính ViewState như thế nào.

Cất giữ thông tin sử dụng Cookies Một cookie là một tên và cặp giá trị mà được cất giữ trong một file nhỏ lưu trữ trên ổ cứng của máy tính khách . Bạn sử dụng tên để xác định giá trị sẽ được lưu trữ; cả tên lẫn giá trị là những đối tượng chuỗi.

Cảnh báo: Những Cookie thì tiềm tàng nghi vấn bởi vì người sử dụng có thể định hình bộ duyệt của họ để ngăn ngừa những Cookie về việc lưu trữ, một bộ duyệt chỉ lưu trữ một lượng hạn chế cookies: 300 trong tổng số và không nhiều hơn 20 đối với một máy chủ phục vụ mạng. Bởi vậy bạn cần phải sử dụng cookies một cách rải rác- nếu là cho mọi thứ. Ví dụ sau đây tạo ra một biến int có tên myInt được gán là 1 và tạo ra một đối tượng HttpCookie cất giữ myInt với tên count:

int myInt = 1; HttpCookie myHttpCookie = new HttpCookie("count", myInt.ToString());

Bởi vì một cookie giữ giá trị như một chuỗi, bạn sử dụng phương thức ToString() để chuyển đổi myInt tới một chuỗi trước khi lưu trữ nó trong myHttpCookie. Để lưu trữ cookie trên máy khách bạn gọi phương thức AppendCookie() của đối tượng Response thuộc đối tượng Page (Trang).

Response.AppendCookie(myHttpCookie);

Đối tượng Response (sự đáp lại) là một đáp ứng HTTP được gửi bởi máy chủ phục vụ Mạng tới bộ duyệt. Khi mã này được chạy, nó yêu cầu bộ duyệt lưu trữ cookie trên đĩa cứng của máy tính khách trong thư mục được chỉ rõ trong sự thiết đặt cho bộ duyệt. Bạn có thể truy xuất giá trị Count từ tập hợp cookies của đối tượng Request (Yêu cầu):

myInt = Int32.Parse(Request.Cookies["count"].Value); Đối tượng Request (Yêu cầu) được gửi bởi bộ duyệt tới máy chủ phục vụ Mạng và chứa cookie vừa gán trước đó. Bởi vì giá trị count được cất giữ như một chuỗi, bạn sử dụng phương thức tĩnh Parse() của cấu trúc Int32 để chuyển đổi chuỗi tới một int.

Page 58: Lap trinhcosodulieuvoi c-sharp_phan-3

Danh sách 15.6 cho thấy một ví dụ của trình ứng dụng ASP .NET sử dụng một cookie để theo dõi số lần trang đã được xem.

Danh sách 15.6: CookieTest.aspx <!-- CookieTest.aspx illustrates the use of a cookie to store information on the client --> <html> <head> <script language="C#" runat="server"> void Page_Load(Object sender, EventArgs e) { int myInt; // check if count is null if (Request.Cookies["count"] == null) { // count is null, so initialize myInt to 1 myInt = 1; // create an HttpCookie object HttpCookie myHttpCookie = new HttpCookie("count", myInt.ToString()); // add HttpCookie object to Response Response.AppendCookie(myHttpCookie); } else { // retrieve count and increment myInt by 1 myInt = Int32.Parse(Request.Cookies["count"].Value) + 1; } // set count value to myInt Response.Cookies["count"].Value = myInt.ToString(); // display myInt in myLabel myLabel.Text = "This page has been viewed "+ myInt.ToString() + " times."; } </script> </head> <body> <asp:Label id="myLabel" runat="server"/> <form runat="server"> <asp:Button text="Press the Button!" runat="server"/> </form> </body> </html>

Ghi chú:

Page 59: Lap trinhcosodulieuvoi c-sharp_phan-3

Chú ý là bạn có thể nhúng mã C# trực tiếp vào trong một file .aspx. file CookieTest.aspx đã được tạo ra sử dụng Microsoft notepad. Để chạy CookieText.aspx, Đơn giản sao chép file này vào trong thư mục Inetpub\wwwroot của bạn và chỉ điểm Bộ duyệt của bạn tới http: // Localhost/ CookieTest.aspx. Hình 15.23 cho thấy trang sinh ra bởi CookieTest.aspx - Giả định rằng nút trên trang đã được nhấn nhiều lần.

Hình 15.23: sự vận hành của trang CookieTest.aspx

Cất giữ thông tin sử dụng thuộc tính ViewState Bạn sử dụng thuộc tính ViewState của đối tượng Page để truy cập một đối tượng StateBag, mà cất giữ một tập hợp tên và những cặp giá trị trên máy tính khách. Bạn sử dụng tên để xác định giá trị đang được cất giữ. Tên là một string (chuỗi) và giá trị là một Object (đối tượng). Không giống một cookie, một người sử dụng không thể cản trở sự lưu trữ những giá trị sử dụng thuộc tính ViewState. Một sử dụng cho thuộc tính ViewState sẽ cất giữ một tên của người sử dụng. Mẹo nhỏ: Một khi những giá trị được gửi qua lại giữa máy khách và máy chủ phục vụ, bạn chỉ nên cất giữ một ít thông tin sử dụng thuộc tính ViewState. Đây là một giải pháp tốt hơn so với sử dụng những cookies bởi vì người sử dụng có thể luôn cản trở sự lưu trữ những cookies. Ví dụ sau đây cất giữ myInt dưới tên count:

int myInt = 1; ViewState["count"] = myInt;

Bạn có thể rồi truy xuất giá trị count sử dụng mã sau đây: myInt = (int) ViewState["count"];

Bởi vì một giá trị được cất giữ như một đối tượng, bạn phải ép nó tới kiểu đặc biệt bạn muốn sử dụng. Trong ví dụ này, giá trị count được ép tới một int. Danh sách 15.7 cho thấy một ví dụ về trang ASP .NET sự sử dụng thuộc tính ViewState để theo dõi số lần trang đã được xem.

<!-- ViewStateTest.aspx illustrates the use of ViewState to store information on the client --> <html> <head> <script language="C#" runat="server"> void Page_Load(Object sender, EventArgs e) { int myInt;

Page 60: Lap trinhcosodulieuvoi c-sharp_phan-3

// check if count is null if (ViewState["count"] == null) { // count is null, so initialize myInt to 1 myInt = 1; } else { // retrieve count and increment myInt by 1 myInt = (int) ViewState["count"] + 1; } // set count value to myInt ViewState["count"] = myInt; // display myInt in myLabel myLabel.Text = "This page has been viewed "+ myInt.ToString() + " times."; } </script> </head> <body> <asp:Label id="myLabel" runat="server"/> <form runat="server"> <asp:Button text="Press the Button!" runat="server"/> </form> </body> </html>

Cất giữ thông tin trên máy chủ phục vụ

Để cất giữ thông tin trên máy chủ phục vụ bạn có thể sử dụng đối tượng phiên họp (Session), ứng dụng (Application) hay bộ đệm (Cache) của đối tượng Page (Trang). Tất cả những đối tượng này lưu trữ thông tin tên và những cặp giá trị trong form , với tên là một chuỗi (string) và giá trị là một đối tượng (Object). Bạn cũng có thể cất giữ thông tin trong bản thân cơ sở dữ liệu, là giải pháp tốt nhất nếu bạn cần cất giữ nhiều thông tin về một người sử dụng hay ứng dụng. Cuối cùng, tất nhiên bạn có thể luôn cất giữ thông tin trong những biến tĩnh hay những đối tượng. Bạn sẽ học về những đối tượng phiên họp, ứng dụng, và bộ đệm trong những mục kế tiếp. Tôi sẽ cũng bàn luận về việc cất giữ thông tin về một ứng dụng mạng trong cơ sở dữ liệu.

Cất giữ thông tin sử dụng một đối tượng Session (Phiên họp) Một đối tượng Session cho phép bạn cất giữ thông tin riêng biệt cho mỗi người sử dụng. Thông tin được cất giữ vào những đối tượng session trên máy chủ phục vụ vẫn duy trì sự tồn tại với một thời gian mặc định là 20 phút, sau thời gian này thông tin được xóa bỏ. Một sử dụng cho đối tượng session có lẽ đã là trữ tên của người sử dụng.

Mẹo nhỏ: bởi vì mỗi đối tượng Session cất giữ thông tin cho một người sử dụng đơn, cất giữ thông tin tối thiểu tuyệt đối cho mỗi người sử dụng. Nếu không, máy chủ phục vụ mạng của các bạn có thể bị ngập với những đối tượng session và sự quá tải bộ nhớ, và ứng dụng của bạn sẽ không hỗ trợ số lượng lớn những người dùng.

Page 61: Lap trinhcosodulieuvoi c-sharp_phan-3

Thông tin được cất giữ trong tên và những cặp giá trị, với tên là một chuỗi và giá trị là một đối tượng. Ví dụ sau đây cất giữ myInt dưới tên Count

int myInt = 1; Session["count"] = myInt;

Rồi bạn có thể truy xuất giá trị count sử dụng mã sau đây:

myInt = (int) Session["count"];

Bởi vì một giá trị được cất giữ như một đối tượng, bạn phải ép nó tới kiểu đặc biệt bạn muốn sử dụng. Trong ví dụ này, giá trị count được ép tới một int. Danh sách 15.8 Trình bày một ví dụ trang ASP.NET sử dụng đối tượng session (Phiên họp) để theo dõi số lần trang đã được xem. Thông tin này riêng biệt đối với mỗi người sử dụng, và do đó hiển thị tổng số lần mà trang đã được xem bởi người sử dụng hiện thời.

Danh sách 15.8: SessionObjectTest.aspx

<!-- SessionObjectTest.aspx illustrates the use of the Session object to store information on the server. This information is specific for each user. --> <html> <head> <script language="C#" runat="server"> void Page_Load(Object sender, EventArgs e) { int myInt; // check if count is null if (Session["count"] == null) { // count is null, so initialize myInt to 1 myInt = 1; } else { // retrieve count and increment myInt by 1 myInt = (int) Session["count"] + 1; } // set count value to myInt Session["count"] = myInt; // display myInt in myLabel myLabel.Text = "This page has been viewed "+ myInt.ToString() + " times."; } </script> </head>

Page 62: Lap trinhcosodulieuvoi c-sharp_phan-3

<body> <asp:Label id="myLabel" runat="server"/> <form runat="server"> <asp:Button text="Press the Button!" runat="server"/> </form> </body> </html>

Cất giữ thông tin sử dụng đối tượng trình ứng dụng Đối tượng trình ứng dụng cho phép bạn cất giữ thông tin mà dùng chung cho tất cả những người sử dụng. Một sử dụng cho đối tượng trình ứng dụng có lẽ để cất giữ một đối tượng Dataset chứa một một danh mục sản phẩm (a product catalog). Thông tin được lưu trữ trong tên và những cặp giá trị, nơi mà tên là một chuỗi và giá trị là một đối tượng. Ví dụ sau đây cất giữ myInt dưới tên count:

int myInt = 1; Application["count"] = myInt;

Bạn có thể rồi truy xuất giá trị count sử dụng mã sau đây

myInt = (int) Application["count"];

Danh sách 15.9 cho thấy một ví dụ ASP.NET page sử dụng đối tượng Application để theo dõi số lần trang đã được xem. Thông tin này được chia sẻ bởi tất cả những người sử dụng, và do đó trình bày tổng số lần trang đã được xem bởi tất cả những người sử dụng. Danh sách 15.9: ApplicationObjectTest.aspx

<!-- ApplicationObjectTest.aspx illustrates the use of the Application object to store information on the server. This information is shared for all users. --> <html> <head> <script language="C#" runat="server"> void Page_Load(Object sender, EventArgs e) { int myInt; // check if count is null if (Application["count"] == null) { // count is null, so initialize myInt to 1 myInt = 1; } else { // retrieve count and increment myInt by 1 myInt = (int) Application["count"] + 1;

Page 63: Lap trinhcosodulieuvoi c-sharp_phan-3

} // set count value to myInt Application["count"] = myInt; // display myInt in myLabel myLabel.Text = "This page has been viewed "+ myInt.ToString() + " times."; } </script> </head> <body> <asp:Label id="myLabel" runat="server"/> <form runat="server"> <asp:Button text="Press the Button!" runat="server"/> </form> </body> </html>

Cất giữ thông tin sử dụng đối tượng bộ đệm Cũng như đối tượng Application , đối tượng Cache (Bộ đệm) cũng được chia sẻ cho tất cả những người sử dụng, nhưng nó cung cấp nhiều chức năng hơn đối tượng ứng dụng. Chẳng hạn, bạn có thể kiểm soát khi thông tin lưu trữ được loại bỏ. Để biết chi tiết hơn về đối tượng Cache (Bộ đệm) tham khảo tài liệu trực tuyến .NET. như được mô tả trong Chương 1, " Giới thiệu về lập trình Cơ sở dữ liệu với ADO.NET." Xem "Cache class" ( lớp Bộ đệm ) trong chỉ mục của tài liệu trực tuyến. Cất giữ thông tin sử dụng Cơ sở dữ liệu Nếu bạn có rất nhiều thông tin để lưu trữ về một người sử dụng, cất giữ nó trong cơ sở dữ liệu tốt hơn là trong đối tượng Cache (Phiên họp). Chẳng hạn, nếu bạn đang xây dựng một trang web mà một người sử dụng có thể đặt mua sản phẩm , lưu trữ " xe đẩy mua hàng " của họ trong cơ sở dữ liệu. @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

Tạo ra một ứng dụng Shopping Cart "xe đẩy mua hàng" đơn giản Trong mục này, bạn sẽ sửa đổi DataGridWebApplication mà bạn tạo ra trước đó để chuyển nó vào trong một "xe đẩy mua hàng " đơn giản. Bạn sẽ cất giữ shopping cart trong một đối tượng Session.

Ghi nhớ: như đã đề cập trong mục trước đây, trong một ứng dụng thực sự bạn sẽ có lẽ muốn lưu trữ shopping cart trong cơ sở dữ liệu hơn là trong một đối tượng Session.

Hình 15.24 trình bày form được chạy cuối cùng mà bạn sẽ xây dựng. Bạn sử dụng nút Buy (mua) để thêm một sản phẩm vào shopping cart ( xe đẩy mua hàng) ở bên phài của form. Như bạn có thể thấy từ Hình 15.24, Tôi có thêm ba sản phẩm vào xe đẩy mua hàng bởi việc nhấn nút buy (mua) cho mỗi sản phẩm trong lưới bên trái.

Page 64: Lap trinhcosodulieuvoi c-sharp_phan-3

Hình 15.24: form đang chạy Bạn có thể theo cả hai bước được trình bày trong những mục sau đây để thêm nút Buy (Mua) và shopping cart (xe đẩy mua hàng) vào form của bạn, hay bạn có thể thay mã ASP.NET trong form của bạn bằng mã trong file WebForm1.aspx được chứa Trong thư mục VS .NET Projects\DataGridWebApplication . Bạn thay thế mã trong form của bạn bởi việc chọn và xóa mã hiện hữu trong form của bạn và dán mã trong file WebForm1.aspx vào. Bạn sẽ cũng cần thay thế mã đằng sau form của bạn với mã trong file WebForm1.aspx.cs được chứa trong thư mục VS .NET Projects\DataGridWebApplication . Thêm nút Buy (mua) Trong mục này, bạn sẽ thêm nút Buy (mua) vào đối tượng DataGrid1 của DataGridWebApplication. Thực hiện những bước sau đây:

1. Mở DataGridWebApplication bởi việc chọn File > Open > Project, nhấn đúp thư mục Data-GridWebApplication , và nhấn đúp file DataGridWebApplication.sln.

2. Mở File WebForm1.aspx trong Degign mode (kiểu thiết kế) bởi nhấn đúp file này trong Solution

Explorer window (cửa sổ Bộ duyệt giải pháp). Kích vào điều khiển DataGrid1 trong form. Hình 15.25 cho thấy những thuộc tính của DataGrid1.

Page 65: Lap trinhcosodulieuvoi c-sharp_phan-3

Figure 15.25: DataGrid1 properties

3. Tiếp theo, kích mối liên kết Property Builder (Bộ xây dựng thuộc tính) gần đáy của cửa sổ những thuộc tính. Thực hiện những bước sau để thêm nút Buy (mua):

1. Kích Columns ở bên trái hộp thoại được những thuộc tính DataGrid1. 2. Mở rộng nút Column của mục Columns sẵn có. 3. Thêm một nút Select vào vùng Selected Columns (những cột được chọn). 4. gán Text là Buy ( Mua). Đây là văn bản được hiển thị trên nút. 5. Gán tên Command là AddToCart. Đây là phương thức được gọi khi nút được nhấn . (Bạn sẽ tạo ra phương pháp này sau .) 6. Gán Button Type ( kiểu nút) tới PushButton (nút nhấn).

Hình 15.26 cho thấy những thuộc tính cuối cùng của nút Buy.

Hình 15.26: những thuộc tính nút Buy

4 Kích OK để thêm nút vào DataGrid1. Hình 15.27 cho thấy DataGrid1 với nút Buy mới thêm vào.

Page 66: Lap trinhcosodulieuvoi c-sharp_phan-3

Hình 15.27: DataGrid1 với nút Buy Thêm Shopping Cart (xe đẩy mua hàng) Trong mục này, bạn sẽ thêm một DataGrid để lưu trữ Shopping Cart (xe đẩy mua hàng). Kéo một điều khiển DataGrid từ Toolbox vào bên trái của DataGrid1 trên form của bạn. Đặt ID của DataGrid mới này là ShoppingCart, như trong Hình 15.28.

Hình 15.28: ShoppingCart DataGrid

Ghi nhớ: Bạn có lẽ đã phải đóng tất cả cửa sổ trừ form designer (cửa sổ thiết kế form) như thế bạn sẽ có đủ không gian màn hình để thêm DataGrid mới vào form của bạn.

Thêm mã vào file WebForm1.aspx.cs. Công việc kế tiếp của bạn là thêm mã bổ sung vào file WebForm1.aspx.cs để hỗ trợ shopping cart (xe đẩy mua hàng). Như được đề cập trước đó, hoặc bạn có thể theo những bước trình bày trong mục này hay bạn có thể thay thế mã đằng sau form của bạn bằng mã trong file WebForm1.aspx.cs được chứa trong thư mục VS .NET Projects\DataGridWebApplication . Bạn thay thế mã trong form của bạn bằng cách chọn và xóa mã hiện hữu trong form và dán mã trong file WebForm1.aspx.cs vào. Thực hiện những bước sau đây nếu bạn muốn tự tay sửa đổi mã:

1. Chọn View Code, hay nhấn F7 trên bàn phím để xem mã. Thêm một đối tượng DataTable đặt tên Cart và một đối tượng DataView tên CartView vào lớp WebForm1, như trình bày trong mã dưới đây:

public class WebForm1 : System.Web.UI.Page { protected DataTable Cart; protected DataView CartView;

Đối tượng Cart của bạn được dùng để lưu trữ shopping cart (xe đẩy mua hàng) và sẽ được cư trú với những sản phẩm được chọn sử dụng nút Buy. Đối tượng CartView của bạn được dùng để xem shopping cart ( xe đẩy mua hàng).

2. Tiếp theo, Gán phương thức Page_Load() tới mã sau đây; chú ý phương pháp này tạo ra một

DataTable để lưu trữ shopping cart (xe đẩy mua hàng), và DataTable này được lưu trữ trong đối tượng

Page 67: Lap trinhcosodulieuvoi c-sharp_phan-3

Session (phiên họp):

private void Page_Load(object sender, System.EventArgs e) { // Put user code to initialize the page here // populate the Session object with the shopping cart if (Session["ShoppingCart"] == null) { Cart = new DataTable(); Cart.Columns.Add(new DataColumn("Product Name", typeof(string))); Cart.Columns.Add(new DataColumn("Unit Price", typeof(string))); Session["ShoppingCart"] = Cart; } else { Cart = (DataTable) Session["ShoppingCart"]; } CartView = new DataView(Cart); ShoppingCart.DataSource = CartView; ShoppingCart.DataBind(); if (!this.IsPostBack) { // populate dataSet11 with the rows from the Products DataTable sqlDataAdapter1.Fill(dataSet11, "Products"); this.DataBind(); } }

3. Tiếp theo, bạn cần thêm phương thức AddToCart() sau đây tới lớp WebForm1 của bạn . Phương thức này được gọi khi người sử dụng nhấn nút Buy (Mua). Chú ý phương thức này tạo ra một đối tượng DataRow và cư trú nó với những đối tượng TableCell để lưu trữ tên sản phẩm và đơn giá trong DataTable Shopping-Cart mà đã thêm vào form bạn trước đó.

protected void AddToCart(Object sender, DataGridCommandEventArgs e) { DataRow product = Cart.NewRow(); // e.Item is the row of the table where the command is raised. // For bound columns the value is stored in the Text property of TableCell TableCell productNameCell = e.Item.Cells[1]; TableCell unitPriceCell = e.Item.Cells[3]; string productName = productNameCell.Text; string unitPrice = unitPriceCell.Text; if (((Button)e.CommandSource).CommandName == "AddToCart") { product[0] = productName; product[1] = unitPrice; Cart.Rows.Add(product); } ShoppingCart.DataBind(); }

4. Việc duy nhất còn lại là chạy form của bạn. Để làm điều này, chọn Debug Start Without Debugging,

hay nhấn Ctrl+ F5 trên bàn phím .

Page 68: Lap trinhcosodulieuvoi c-sharp_phan-3

Kích nút Buy cho những sản phẩm khác nhau trong lưới để thêm chúng vào xe đẩy mua hàng của bạn. @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

Tóm lược HTML tạo ra những trang Web tĩnh với nội dung không thay đổi. Tuy nhiên,nếu bạn muốn thông tin động, thì bạn có thể sử dụng ASP.NET. Nó cho phép bạn tạo ra những trang Web 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 mà được truy cập sử dụng một Web Browser (Trình duyệt mạng). Trong chương này, bạn đã thấy cách sử dụng Visual Studio .NET và ngôn ngữ lập trình C# để tạo một vài trình ứng dụng Web đơn giản ASP.NET . Chương này cho bạn một giới thiệu ngắn gọn về đề tài lớn ASP.NET. Về phạm vi đề tài kỹ lưỡng hơn , xem "Mastering ASP .NET with C# (Sybex, 2002)" của Russell Jones. Có hai phần chính tới form ASP.NET : file .aspx, chứa mã HTML và ASP .NET , và file aspx.cs , chứa mã C# mà hỗ trợ form web. Bạn có thể xem mã C# này như một thứ chạy đằng sau form, và vì lý do này file .aspx.cs được biết như file sau mã. Bạn có thể xem mã ASP.NET chứa trong file HTML cho form của bạn bởi việc kích mối liên kết HTML ở đáy cửa sổ fom deginer . Bạn có thể xem file sau mã bởi chọn View > Code, hay bạn có thể nhấn F7 trên bàn phím. 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 trình ứ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 như thế nào. 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ộ xây dựng thuộc tính) ở đáy của cửa sổ những thuộc tính. Việc 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 vào trong nă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). Một DataList cung cấp cho bạn nhiều tính linh hoạt trong sự trình bày những giá trị cột hơn một DataGrid, Như khả năng thêm những đầu mục và những cuối vào dữ liệu. Giao thức truyền tải siêu văn bản (HTTP) không bảo trì trạng thái giữa những trang cung cấp bởi máy chủ phục vụ Mạng của bạn trong thời gian mỗi vòng truyền tải. Điều này có nghĩa là bất kỳ thông tin nào bạn cung cấp trong một form sẽ bị bỏ quên khi bạn nhận một trang mới. Để Máy chủ phục vụ Mạng nhớ những gì bạn đã làm trong thời gian vòng truyền tải sau cùng , bạn có thể cất giữ thông tin trên Máy chủ phục vụ hay trên máy tính khách trên đó trình duyệt đang chạy. Việc lưu trữ thông tin trên máy khách có nghĩa là bạn không sử dụng bất kỳ tài nguyên nào trên máy chủ phục vụ để lưu trữ thông tin này và trình ứng dụng web của bạn có thể xử lý nhiều người sử dụng hơn. Việc lưu trữ thông tin trên máy chủ phục vụ cho bạn nhiều điều khiển của thông tin được cất giữ hơn, nhưng từ đó tiêu thụ những tài nguyên máy chủ phục vụ, bạn cần cẩn thận không lưu trữ quá nhiều; nếu không ứng dụng web của bạn sẽ không có khả năng xử lý nhiều người sử dụng. @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

Chương 16: Sử dụng hỗ trợ XML của máy chủ phục vụ SQL

Tổng quan XML đã trở nên một ngôn ngữ chung của web bởi vì đó là một định dạng lý tưởng cho sự trao đổi thông tin. Đã có rất nhiều công ty trao đổi thông tin lẫn nhau sử dụng XML được gửi qua Mạng. Trong chương này, bạn sẽ học về sự hỗ trợ XML rộng lớn của máy chủ phục vụ SQL. Bạn sẽ cũng thấy cách để cất giữ XML ở một chương trình C# sử dụng những đối tượng XmlDocument và XmlDataDocument. Những đặc trưng trong chương này:

■ Sử dụng mệnh đề FOR XML của SQL Server

Page 69: Lap trinhcosodulieuvoi c-sharp_phan-3

■ Giới thiệu XPath và XSLT ■ Truy cập máy chủ phục vụ SQL sử dụng HTTP ■ Sử dụng hàm OPENXML() của SQL server ■ Sử dụng một đối tượng XmlDocument để lưu trữ một tệp tài liệu XML (XML document). ■ Sử dụng một đối tượng XmlDataDocument để lưu một tệp tài liệu XML (XML document).

Sử dụng mệnh đề FOR XML của SQL Server Với một phát biểu SELECT SQL tiêu chuẩn , bạn gởi phát biểu SELECT của bạn tới cơ sở dữ liệu cho sự thực thi và lấy lại những kết quả trong form của những hàng. SQL Server mở rộng phát biểu SELECT để cho phép bạn truy vấn cơ sở dữ liệu và lấy về những kết quả dạng XML. Để làm điều này bạn thêm một mệnh đề FOR XML vào cuối của phát biểu SELECT của bạn. Mệnh đề for XML chỉ định máy chủ phục vụ SQL sẽ trả lại những kết quả dạng XML. Mệnh đề FOR XML có cú pháp như sau đây:

FOR XML {RAW | AUTO | EXPLICIT} [, XMLDATA] [, ELEMENTS] [, BINARY BASE64]

Những từ khóa RAW, AUTO, và EXPLICIT chỉ báo kiểu XML. Bảng 16.1 cho thấy một sự mô tả của những từ khóa được dùng trong mệnh đề FOR XML. Trong những mục kế tiếp, bạn sẽ khảo sát một số ví dụ về sự sử dụng của mệnh đề FOR XML. Bảng 16.1: Những từ khóa FOR XML

Từ khóa Mô tả RAW Chỉ rõ mỗi hàng trong tập hợp kết quả được trả về như một phần tử < row>XML . Những giá trị

cột cho mỗi hàng trong tập hợp kết quả trở thành những thuộc tính của phần tử <row> .

AUTO Chỉ rõ mỗi hàng trong tập hợp kết quả được trả về như một phần tử XML, tên của bảng được sử dụng như tên của thẻ trong những phần tử hàng.

EXPLICIT Cho biết phát biểu SELECT của bạn chỉ rõ một mối quan hệ cha con. Mối quan hệ này rồi được sử dụng bởi máy chủ phục vụ SQL để phát sinh XML với sự phân cấp thích hợp được lồng vào .

XMLDATA Chỉ rõ mô hình XML sẽ được bao gồm trong XML được trả về.

ELEMENTS Chỉ rõ những giá trị cột được trả về như những phần tử của hàng; cách khác những cột được trả về như những thuộc tính của hàng. Bạn chỉ có thể sử dụng tùy chọn này với kiểu AUTO.

BINARY BASE64

Chỉ rõ bất kỳ dữ liệu nhị phân nào được trả về bởi phát biểu SELECT của bạn đều được mã hóa trong cơ sở 64. Nếu bạn muốn truy xuất dữ liệu nhị phân sử dụng hoặc kiểu RAW hoặc kiểu EXPLICIT, thì bạn phải sử dụng tùy chọn BINARY BASE64.

Sử dụng kiểu RAW

Page 70: Lap trinhcosodulieuvoi c-sharp_phan-3

Bạn sử dụng kiểu RAW để chỉ rõ mỗi hàng trong tập hợp kết quả được trả về bởi phát biểu SELECT của bạn được trở về như một phần tử < Hàng>XML . Những giá trị cột cho mỗi hàng trong tập hợp kết quả trở thành những thuộc tính của phần tử <row> . Danh sách 16.1 cho thấy một ví dụ về phát biểu SELECT mà truy xuất ba hàng đầu tiên từ bảng Customers. Những kết quả SELECT được trả về với dạng XML sử dụng mệnh đề FOR XML RAW. Danh sách 16.1: FORXMLRAW.SQL

USE Northwind SELECT TOP 3 CustomerID, CompanyName, ContactName FROM Customers ORDER BY CustomerID FOR XML RAW

Ghi chú: Phát biểu SELECT này được chứa trong một script T-SQL có tên ForXmlRaw.sql, được định vị trong thư mục sql cho chương này .

Bạn có thể tải script ForXmlRaw.sql T- SQL vào trong Query Analyzer (bộ phân tích truy vấn) bởi chọn File > Open từ thực đơn menu. Rồi bạn chạy script bởi chọn Query > Execute, hay bởi nhấn khóa F5. Hình 16.1 cho thấy kết quả của việc chạy script trong Query Anlyzer. Bạn chú ý là XML được hiện ra trên một hàng, và hàng này bị xén bớt.

Hình 16.1: việc chạy một phát biểu SELECT chứa một mệnh đề FOR RAW XML trong Query Analyzer

Ghi chú: Theo mặc định, số lượng ký tự cực đại được trình bày bởi Query Analyzer trên cột là 256. Bất kỳ kết quả nào dài hơn 256 ký tự sẽ được cắt bỏ. Cho những ví dụ trong mục này bạn sẽ cần tăng số cực đại của những ký tự tới 8,192. Để làm điều này, bạn chọn Tools > Option trong Query Analyzer và gán trường số ký tự cực đại mỗi cột tới 8,192.

Đây là hàng XML được trả về bởi ví dụ, mà Tôi sao chép từ "bộ phân tích truy vấn" và thêm một số ký tự trả về để làm cho nó dễ đọc hơn

<row CustomerID="ALFKI" CompanyName="Alfreds Futterkiste" ContactName="Maria Anders"/>

Page 71: Lap trinhcosodulieuvoi c-sharp_phan-3

<row CustomerID="ANATR" CompanyName="Ana Trujillo Emparedados y helados" ContactName="Ana Trujillo"/> <row CustomerID="ANTON" CompanyName="Antonio Moreno Taquería" ContactName="Antonio Moreno"/>

Chú ý là thông tin về mỗi khách hàng được đặt bên trong một thẻ < row> . Đồng thời, những giá trị cột xuất hiện như những thuộc tính bên trong mỗi hàng; chẳng hạn, trong hàng đầu tiên, thuộc tính CustomerID là ALFKI.

Sử dụng kiểu AUTO

Bạn sử dụng kiểu AUTO để chỉ rõ mỗi hàng trong tập hợp kết quả được trả về như một phần tử XML. Tên của bảng được sử dụng như tên của thẻ trong những phần tử hàng. Danh sách 16.2: FORXMLAUTO.SQL

USE Northwind SELECT TOP 3 CustomerID, CompanyName, ContactName FROM Customers ORDER BY CustomerID FOR XML AUTO

XMLđược trả về bởi ví dụ này như sau:

<Customers CustomerID="ALFKI" CompanyName="Alfreds Futterkiste" ContactName="Maria Anders"/> <Customers CustomerID="ANATR" CompanyName="Ana Trujillo Emparedados y helados" ContactName="Ana Trujillo"/> <Customers CustomerID="ANTON" CompanyName="Antonio Moreno Taquería" ContactName="Antonio Moreno"/>

Chú ý mỗi khách hàng xuất hiện bên trong một thẻ <Customer> thay vì một thẻ < row> , như trường hợp trong ví dụ kiểu RAW trước đây.

Sử dụng kiểu EXPLICIT:

Bạn sử dụng kiểu EXPLICIT để cho biết phát biểu SELECT của bạn chỉ rõ một mối quan hệ cha con. Mối quan hệ này rồi được sử dụng bởi máy chủ phục vụ SQL để phát sinh XML với sự phân cấp thích hợp được lồng vào . Khi sử dụng kiểu EXPLICIT bạn phải cung cấp ít nhất hai phát biểu SELECT. SELECT thứ nhất chỉ rõ hàng cha (hay những hàng), và SELECT thứ hai chỉ rõ những hàng con. Những hàng được truy xuất bởi hai sự phát biểu

Page 72: Lap trinhcosodulieuvoi c-sharp_phan-3

SELECT có liên quan thông qua những cột đặc biệt có tên Tag và Parent. Tag chỉ rõ vị trí số của phần tử, và Parent chỉ rõ số tag của phần tử Cha (nếu có). Chúng ta hãy cho rằng một ví dụ mà sử dụng hai phát biểu SELECT. SELECT đầu tiên truy xuất CustomerID, CompanyName, Và ContactName cho hàng từ bảng Customers có một CustomerID là ALFKI. SELECT thứ hai đồng thời truy xuất OrderID và OrderDate từ hàng trong bảng Orders mà cũng có một CustomerID là ALFKI. Phát biểu SELECT đầu tiên như sau:

SELECT 1 AS Tag, 0 AS Parent, CustomerID AS [Customer!1!CustomerID], CompanyName AS [Customer!1!CompanyName], ContactName AS [Customer!1!ContactName], NULL AS [Order!2!OrderID!element], NULL AS [Order!2!OrderDate!element] FROM Customers WHERE CustomerID = 'ALFKI'

Cột Tag chỉ rõ vị trí số của hàng trong sự phân cấp XML. Cột Parent xác định cột Cha , mà là 0 trong phát biểu SELECT trước đây; đó là bởi vì hàng này là cha , hay root, trong sự phân cấp XML.

Ghi chú: Bạn cũng có thể sử dụng một giá trị Tag là Null để chỉ báo root (gốc rể)

Những cột CustomerID, CompanyName, và ContactName trong SELECT trước đây được cung cấp một bí danh sử dụng từ khóa AS, đi theo sau bởi một chuỗi mà sử dụng định dạng sau đây:

[elementName!tag!attributeName!directive] VỚI:

elementName chỉ rõ tên của phần tử hàng trong XML được trả lại. Tag: chỉ rõ số thẻ (Tag). attributeName: chỉ rõ tên của những phần tử cột trong XML được trả lại. directive : (tùy chọn) chỉ rõ phần tử sẽ được xử lý như thế nào trong XML. Những chỉ thị được trình bày trong Bảng 16.2.

Bảng 16.2: DIRECTIVES Chỉ thị Mô tả

element Chỉ báo giá trị cột xuất hiện như một phần tử hàng được chứa bên trong phần tử hàng bên ngoài, đúng hơn là một thuộc tính nhúng của phần tử hàng bên ngoài . phần tử chỉ thị có thể kết hợp với ID, IDREF, hay IDREFS.

hide Chỉ báo giá trị cột không xuất hiện trong XML được trả về. xml Tương tự như chỉ thị phần tử ngoại trừ giá trị cột không được viết mã như một thực thể trong

XML được trả về. Có nghĩa là những ký tự đặc biệt &, ',>,<, và " để lại như nó có". Nếu không, những ký tự này sẽ được viết mã như &amp;, &apos;, &gt;, &lt;, và &quot; tương ứng. Chỉ thị xml có thể kết hợp với hide.

xmltext Chỉ báo giá trị cột được chứa trong một thẻ đơn. Sử dụng chỉ thị xmltext, kiểu cột của bạn phải là varchar, nvarchar, char, nchar, text, hay ntext.

cdata Chỉ báo giá trị cột được chứa bên trong một mục CDATA. Những mục CDATA được dùng để thoát khỏi những khối văn bản chứa những ký tự đặc biệt mà nếu không sẽ được giải thích như nhãn phụ; những ký tự này bao gồm &, >,<, và ". để sử dụng chỉ thị cdata, kiểu cột của bạn phải

Page 73: Lap trinhcosodulieuvoi c-sharp_phan-3

là varchar, nvarchar, text, hay ntext. ID Chỉ báo giá trị cột là một thuộc tính ID. Một thuộc tính IDREF và IDREFS có thể trỏ vào một

thuộc tính ID, cho phép bạn tạo ra những mối liên kết bên trong XML. IDREF Chỉ báo giá trị cột là một thuộc tính IDREF. IDREFS Chỉ báo giá trị cột là một thuộc tính IDREFS.

Chúng ta hãy xem xét một ví dụ: CustomerID như [Customer!1!CustomerID] chỉ rõ giá trị cột CustomerID sẽ xuất hiện bên trong phần tử hàng Customers với tên thuộc tính của CustomerID. Sau ContactName trong mệnh đề SELECT trước đây, xuất hiện hai cột có giá trị NULL; chúng được sử dụng như placeholders (bộ giử chỗ) cho những cột OrderID và OrderDate được truy xuất bởi hai phát biểu SELECT, mà bạn sẽ thấy tiếp theo đây. Hai cột này sử dụng chỉ thị element, mà chỉ báo những giá trị cột sẽ xuất hiện như những phần tử được chứa bên trong phần tử hàng Customers. Phát biểu SELECT thứ hai truy xuất những hàng từ bảng Orders có một CustomerID là ALFKI:

SELECT 2 AS Tag, 1 AS Parent, C.CustomerID, C.CompanyName, C.ContactName, O.OrderID, O.OrderDate FROM Customers C, Orders O WHERE C.CustomerID = O.CustomerID AND C.CustomerID = 'ALFKI'

Chú ý là cột Parent được gán tới 1, nó cho biết Parent là hàng được truy xuất trước đó bởi phát biểu SELECT đầu tiên trình bày trước đó. Danh sách 16.3 cho thấy một ví dụ đầy đủ sử dụng hai phát biểu SELECT trình bày trong mục này. Danh sách 16.3: FORXMLEXPLICIT.SQL

USE Northwind SELECT 1 AS Tag, 0 AS Parent, CustomerID AS [Customer!1!CustomerID], CompanyName AS [Customer!1!CompanyName], ContactName AS [Customer!1!ContactName], NULL AS [Order!2!OrderID!element], NULL AS [Order!2!OrderDate!element] FROM Customers WHERE CustomerID = 'ALFKI' UNION ALL SELECT 2 AS Tag, 1 AS Parent, C.CustomerID, C.CompanyName, C.ContactName,

Page 74: Lap trinhcosodulieuvoi c-sharp_phan-3

O.OrderID, O.OrderDate FROM Customers C, Orders O WHERE C.CustomerID = O.CustomerID AND C.CustomerID = 'ALFKI' FOR XML EXPLICIT

Ghi nhớ: Mệnh đề UNION ALL gây cho những kết quả truy xuất được bởi hai phát biểu SELECT sẽ được trộn vào trong một tập hợp kết quả.

Tập hợp kết quả kết hợp được sản xuất bởi mệnh đề UNION ALL được chuyển đổi thành XML bởi mệnh đề FOR XML EXPLICIT. XML trả về bởi ví dụ như sau:

<Customer CustomerID="ALFKI" CompanyName="Alfreds Futterkiste" ContactName="Maria Anders"> <Order> <OrderID>10643</OrderID> <OrderDate>1997-08-25T00:00:00</OrderDate> </Order> <Order> <OrderID>10692</OrderID> <OrderDate>1997-10-03T00:00:00</OrderDate> </Order> <Order> <OrderID>10702</OrderID> <OrderDate>1997-10-13T00:00:00</OrderDate> </Order> <Order> <OrderID>10835</OrderID> <OrderDate>1998-01-15T00:00:00</OrderDate> </Order> <Order> <OrderID>10952</OrderID> <OrderDate>1998-03-16T00:00:00</OrderDate> </Order> <Order> <OrderID>11011</OrderID> <OrderDate>1998-04-09T00:00:00</OrderDate> </Order> </Customer>

Chú ý rằng phần tử OrderID và OrderDate xuất hiện như những phần tử hàng chứa trong phần tử Order phía ngoài. Đây là bởi vì chỉ thị phần tử được chỉ định cho những phần tử OrderID và OrderDate trong phát biểu SELECT đầu tiên. Nếu chỉ thị phần tử bị bỏ sót từ những phần tử OrderID và OrderDate, thì XML được trả về như sau:

<Customer CustomerID="ALFKI" CompanyName="Alfreds Futterkiste" ContactName="Maria Anders"> <Order OrderID="10643" OrderDate="1997-08-25T00:00:00"/> <Order OrderID="10692" OrderDate="1997-10-03T00:00:00"/>

Page 75: Lap trinhcosodulieuvoi c-sharp_phan-3

<Order OrderID="10702" OrderDate="1997-10-13T00:00:00"/> <Order OrderID="10835" OrderDate="1998-01-15T00:00:00"/> <Order OrderID="10952" OrderDate="1998-03-16T00:00:00"/> <Order OrderID="11011" OrderDate="1998-04-09T00:00:00"/> </Customer>

Chú ý là những phần tử OrderID và OrderDate được nhúng như những thuộc tính của phần tử Order bên ngoài. Sử dụng tùy chọn XMLDATA Bạn sử dụng tùy chọn XMLDATA để chỉ định định nghĩa kiểu tài liệu mô hình XML (DTD) sẽ được bao gồm trong XML được trả về. Mô hình XML chứa tên và kiểu của những thuộc tính cột. Danh sách 16.4 trình bày một ví dụ sử dụng tùy chọn XMLDATA để trả về mô hình XML cùng với Những cột ProductID, ProductName, và UnitPrice cho hai hàng đầu tiên từ bảng Products. Danh sách 16.4: FORXMLAUTOXMLDATA.SQL

USE Northwind SELECT TOP 2 ProductID, ProductName, UnitPrice FROM Products ORDER BY ProductID FOR XML AUTO, XMLDATA

Ghi nhớ: Trong ví dụ này, Tôi sử dụng những cột từ bảng Products hơn là bảng Customers bởi vì những bảng Customers chỉ chứa những giá trị cột chuỗi, và Tôi muốn bạn thấy một số những kiểu khác nhau được trả về trong một mô hình XML. Bảng Products chứa những giá trị cột bao gồm cả những chuỗi lẫn những số.

Cột ProductID thuộc kiểu int SQL Server, ProductName thuộc kiểu nvarchar, và UnitPrice thuộc kiểu money (tiền tệ). XML trả về bởi ví dụ này như sau:

<Schema name="Schema3" xmlns="urn:schemas-microsoft-com:xml-data" xmlns:dt="urn:schemas-microsoft-com:datatypes"> <ElementType name="Products" content="empty" model="closed"> <AttributeType name="ProductID" dt:type="i4"/> <AttributeType name="ProductName" dt:type="string"/> <AttributeType name="UnitPrice" dt:type="fixed.14.4"/> <attribute type="ProductID"/> <attribute type="ProductName"/> <attribute type="UnitPrice"/> </ElementType> </Schema> <Products xmlns="x-schema:#Schema3" ProductID="1" ProductName="Chai" UnitPrice="18.0000"/> <Products xmlns="x-schema:#Schema3" ProductID="2" ProductName="Chang" UnitPrice="19.0000"/>

Chú ý những kiểu XML khác nhau của những thuộctính ProductID, ProductName, và UnitPrice được chỉ

Page 76: Lap trinhcosodulieuvoi c-sharp_phan-3

định trong thẻ AttributeType gần đoạn khởi đầu của XML trước đây. Để biết chi tiết hơn, xem những mô hình XML viết bởi Chelsea Valentine, Lucinda Dykes, and Ed Tittel (Sybex, 2002). Sử dụng những tùy chọn ELEMENT Bạn sử dụng những tùy chọn ELEMENTS để chỉ định những giá trị cột được trả về như những phần tử phụ của hàng; nếu không những giá trị cột được trở về như những thuộc tính của hàng.

Mẹo nhỏ: Bạn chỉ có thể sử dụng những tùy chọn ELEMENTS với AUTO mode. Danh sách 16.5 cho thấy một ví dụ sử dụng tùy chọn ELEMENTS khi truy xuất hai hàng đầu tiên từ bảng Customers. Danh sách 16.5: FORXMLAUTOELEMENTS.SQL

USE Northwind SELECT TOP 2 CustomerID, CompanyName, ContactName FROM Customers ORDER BY CustomerID FOR XML AUTO, ELEMENTS

XML trả về bởi ví dụ này như sau:

<Customers> <CustomerID>ALFKI</CustomerID> <CompanyName>Alfreds Futterkiste</CompanyName> <ContactName>Maria Anders</ContactName> </Customers> <Customers> <CustomerID>ANATR</CustomerID> <CompanyName>Ana Trujillo Emparedados y helados</CompanyName> <ContactName>Ana Trujillo</ContactName> </Customers>

Chú ý : những giá trị cột được trả về như những phần tử phụ bên trong những hàng của Customers.

Sử dụng tùy chọn BASE64 Nhị phân Bạn sử dụng tùy chọn BINARY BASE64 để chỉ định bất kỳ dữ liệu nhị phân nào được trả về bởi phát biểu SELECT của bạn đều được mã hóa trong cơ số 64. Ghi nhớ : Nếu bạn muốn truy xuất dữ liệu nhị phân sử dụng hoặc kiểu RAW hay EXPLICIT, thì bạn phải sử dụng tùy chọn BINARY BASE64 . Trong những ví dụ trong mục này, Tôi sẽ sử dụng bảng Employees (công nhân) của cơ sở dữ liệu Northwind. Bảng này chứa những chi tiết của Employees làm việc cho công ty hư cấu Northwind và chứa một cột có tên Photo .Cột Photo thuộc kiểu image SQL Server và chứa dữ liệu nhị phân với một ảnh của một công nhân. Hình 16.2 cho thấy một phát biểu SELECT chạy trong Query Analyzer nó truy xuất những cột EmployeeID (khóa chính), FirstName, LastName, và Photo từ bảng Employees. Chú ý rằng dữ liệu nhị phân được truy xuất như những số hệ 16 ( cơ số16).

Page 77: Lap trinhcosodulieuvoi c-sharp_phan-3

Hình 16.2: Truy xuất những hàng từ bảng Employees Trong kiểu AUTO, dữ liệu nhị phân được trả về theo mặc định như một tham chiếu tới dữ liệu thay vì bản thân dữ liệu . Ví dụ sau đây truy xuất những cột EmployeeID và Photo cho hai hàng đầu tiên từ bảng Employees sử dụng kiểu AUTO:

USE Northwind SELECT TOP 2 EmployeeID, Photo FROM Employees ORDER BY EmployeeID FOR XML AUTO

Ví dụ này trả về XML sau đây:

<Employees EmployeeID="1" Photo="dbobject/Employees[@EmployeeID='1']/@Photo"/> <Employees EmployeeID="2" Photo="dbobject/Employees[@EmployeeID='2']/@Photo"/>

Tham chiếu tới dữ liệu nhị phân được chứa trong cột Photo thật sự là một biểu thức XPath. (Bạn sẽ học về XPath trong mục kế tiếp.) Để lấy chính bản thân dữ liệu nhị phân, thay vì tham chiếu tới nó, bạn cần sử dụng tùy chọn BINARY BASE64 . Danh sách 16.6 trình bày một ví dụ sử dụng tùy chọn BINARY BASE64 khi truy xuất những cột EmployeeID và Photo cho hai hàng đầu tiên từ bảng Employees. Danh sách 16.6: FORXMLAUTOBINARYBASE64. SQL

USE Northwind SELECT TOP 2 EmployeeID, Photo FROM Employees ORDER BY EmployeeID FOR XML AUTO, BINARY BASE64

---------------------------------------------------------------------- XML được trả về bởi ví dụ này như sau:

<Employees EmployeeID="1" Photo="FRwvAAIAAA…"/> <Employees

Page 78: Lap trinhcosodulieuvoi c-sharp_phan-3

EmployeeID="2" Photo="FRwvAAIAAA…"/>

Ghi chú: Tôi chỉ trình bày 10 chữ số đầu tiên của dữ liệu nhị phân. Để xem dữ liệu nhị phân trong Query Analyzer, bạn sẽ cần gán “đích của những kết quả mặc định” là Text trong "hộp thoại những tùy chọn". Bạn chọn Tool > Options từ thực đơn menu để hiển thị hộp thoại này.

Giới thiệu XPath Ngôn ngữ đánh dấu mở rộng đường dẫn (XPath) là một Ngôn ngữ cho phép bạn tìm kiếm và định hướng một tài liệu XML, và bạn có thể sử dụng XPath với máy chủ phục vụ SQL. Trong mục này bạn sẽ khám phá cấu trúc của một tài liệu XML (XML document ) và cách để định hướng và tìm kiếm một tài liệu XML sử dụng XPath như thế nào. Trong những mục sau đó, bạn sẽ học cách sử dụng XPath với máy chủ phục vụ SQL như thế nào.

Cấu trúc Tài liệu XML Một file tài liệu XML được chia vào trong những nút, với nút cao nhất được tham chiếu tới như nút gốc (root node). Cách dễ dàng nhất để hiểu cấu trúc làm việc như thế nào là xem xét một tài liệu XML ví dụ; Danh sách 16.7 cho thấy một tài liệu XML chứa trong file Customers.xml. Danh sách 16.7: CUSTOMERS.XML

<?xml version="1.0"?> <NorthwindCustomers> <Customers> <CustomerID>ALFKI</CustomerID> <CompanyName>Alfreds Futterkiste</CompanyName> <PostalCode>12209</PostalCode> <Country>Germany</Country> <Phone>030-0074321</Phone> </Customers> <Customers> <CustomerID>ANATR</CustomerID> <CompanyName>Ana Trujillo Emparedados y helados</CompanyName> <PostalCode>05021</PostalCode> <Country>Mexico</Country> <Phone>(5) 555-4729</Phone> </Customers> </NorthwindCustomers>

Ghi nhớ: Bạn sẽ tìm thấy tất cả những file XML trong thư mục xml cho chương này.

Ghi nhớ: phiên bản <?xml version="1.0"?> chỉ định là Customers.xml này là một file XML sử dụng tiêu chuẩn 1.0.

Hình 16.3 cho thấy một sự trình bày trực quan của cấu trúc tài liệu Customers.xml .

Page 79: Lap trinhcosodulieuvoi c-sharp_phan-3

Hình 16.3: Cấu trúc tài liệu Customers.xml Như bạn có thể thấy từ Hình 16.3, một tài liệu XML có cấu trúc như một cây đảo ngược. NorthwindCustomers là nút gốc (root node). Hai nút Customers ở dưới nút gốc được biết như một tập hợp nút (a node set). CustomerID, CompanyName, PostalCode, Country, và Phone được biết như những phần tử (elements). Mỗi nút Customers và những phần tử CustomerID, CompanyName, PostalCode , Country, và Phone của nó được biết như một cây con nút (a node subtree). Một nút được định vị ở dưới nút khác được biết như một nút con (child node), và nút ở trên được biết như nút cha (parent node); chẳng hạn, nút NorthwindCustomers là nút cha của những nút con Customers. Bạn có thể xem một file XML sử dụng Microsoft Internet Explorer , như trong Hình 16.4.

Hình 16.4: xem Customers.xml trong Internet Explorer

Mẹo nhỏ: để mở file XML, nhấn phải Customers.xml trong Windows Explorer và chọn Open With > Internet Explorer từ thực đơn sổ ra.

Những biểu thức XPath

Page 80: Lap trinhcosodulieuvoi c-sharp_phan-3

Để tìm kiếm hay định hướng một file tài liệu XML bạn cung cấp một biểu thức cho XPath. Những biểu thức này làm việc bên trong một ngữ cảnh (a context), là nút hiện thời được truy cập bên trong file XML. Những cách thường sử dụng nhất về việc chỉ định ngữ cảnh được trình bày trong Bảng 16.3. Bảng 16.3: sự chỉ định ngữ cảnh

Những ký tự Mô tả / Chỉ định nút gốc như ngữ cảnh. ./ Chỉ định nút hiện thời như ngữ cảnh. ../ Chỉ định nút cha mẹ như ngữ cảnh. // Chỉ định toàn bộ tài liệu XML như ngữ cảnh. .// Chỉ định toàn bộ tài liệu XML bắt đầu tại nút hiện thời như ngữ cảnh.

Chúng ta hãy xem xét một số ví dụ về biểu thức XPath . Ví dụ sau đây trả về những nút Customers: /NorthwindCustomers/Customers Như bạn có thể thấy từ ví dụ này, bạn chỉ rõ đường dẫn xuống cấu trúc cây để chỉ rõ những nút, phân chia mỗi nút với một ký tự gạch chéo (/). //Customers Ví dụ kế tiếp trả về những nút Customers và tất cả các phần tử của chúng: /NorthwindCustomers/Customers/*

Ghi nhớ: dấu sao (*) chỉ định tất cả những phần tử Ví dụ kế tiếp trả về chỉ phần tử CustomerID của những nút Customers :

/NorthwindCustomers/Customers/CustomerID

Bạn có thể tìm thấy những phần tử trong một nút bởi việc chỉ định một sự tìm kiếm bên trong dấu ngoặc vuông []. Ví dụ sau đây trả về tất cả những phần tử của khách hàng có một CustomerID là ALFKI:

/NorthwindCustomers/Customers[CustomerID="ALFKI"]/* Ví dụ sau đây trả về CompanyName của khách hàng với một CustomerID là ALFKI:

/NorthwindCustomers/Customers[CustomerID="ALFKI"]/CompanyName Bạn cũng có thể sử dụng những dấu ngoặc vuông để chỉ định chỉ số của một nút, bắt đầu tại chỉ số 1. Ví dụ sau đây trả lại nút đầu tiên Customers:

/NorthwindCustomers/Customers[1] Bạn có thể sử dụng hàm last() để lấy nút cuối cùng. Ví dụ sau đây trả lại nút cuối cùng Customers:

/NorthwindCustomers/Customers[last()] Nếu file XML của bạn chứa những thuộc tính nhúng thay vì những phần tử để giữ những giá trị, thì biểu thức tìm kiếm XPath của bạn sẽ hơi khác nhau. Danh sách 16.8 cho thấy một file XML có tên CustomersWithAttributes.xml sử dụng những thuộc tính này. Danh sách 16.8: CUSTOMERSWITHATTRIBUTES.XML

<?xml version="1.0"?>

Page 81: Lap trinhcosodulieuvoi c-sharp_phan-3

<NorthwindCustomers> <Customers CustomerID="ALFKI" CompanyName="Alfreds Futterkiste" PostalCode="12209" Country="Germany" Phone="030-0074321" /> <Customers CustomerID="ANATR" CompanyName="Ana Trujillo Emparedados y helados" PostalCode="05021" Country="Mexico" Phone="(5) 555-4729" /> </NorthwindCustomers>

Để truy cập một thuộc tính bạn đặt một ký tự (@) tại điểm bắt đầu của tên thuộc tính. ví dụ sau đây trả về thuộc tính CustomerID của những nút Customers:

/NorthwindCustomers/Customers/@CustomerID Ví dụ kế tiếp trả về tất cả những thuộc tính của khách hàng với một CustomerID là ALFKI: /NorthwindCustomers/Customers[@CustomerID="ALFKI"]/* Ví dụ sau đây trả về CompanyName của khách hàng với một CustomerID là ALFKI:

/NorthwindCustomers/Customers[@CustomerID="ALFKI"]/@CompanyName Ghi nhớ: Tôi đã chỉ bàn đến những biểu thức XPath trong mục này. Bạn có thể sử dụng nhiều tóan tử toán học khác, những biểu thức đại số Boole và nhiều hơn nữa. Bạn có thể học nhiều hơn về XPath trong tài liệu sách trực tuyến của máy chủ phục vụ SQL và tại World Wide Web Consortium's (WC3) Web site tại www.w3.org; hãy tìm về XPath trong bảng mục lục. Giới thiệu XSLT XML là một cách tuyệt vời để trình bày dữ liệu trong một định dạng linh động, nhưng XML không chứa thông tin về việc làm sao để định dạng dữ liệu này cho sự hiển thị. Extensible Stylesheet Language Transformation (Sự biến đổi ngôn ngữ Stylesheet mở rộng) (XSLT) cho phép bạn kiểm soát sự định dạng của dữ liệu XML, và có thể thường thay đổi dữ liệu XML tới một định dạng thích hợp để trình bày nó như một tài liệu. Một stylesheet XSL - cũng được biết đến như một file XSLT- là một khuôn mẫu chứa những quy tắc mô tả dữ liệu trong file XML sẽ được định dạng như thế nào cho sự hiển thị. File XML và XSLT được xử lý cùng nhau bởi một bộ xử lý XSLT. Những quy tắc được định nghĩa trong file XSLT được ứng dụng vào dữ liệu trong file XML, và kết quả cuối cùng được xuất ra bởi bộ xử lý XSLT.Microsoft Internet Explorer chứa một bộ xử lý XSLT, và bạn sẽ thấy những ví dụ trong mục này trình bày những kết quả của sự xử lý một file XML và XSLT trong Internet Explorer.

Ghi chú : Internet Explorer thật sự đến cùng với một file XSLT mặc định, nó gây cho những file XML sử dụng những màu khác nhau cho những phần của tài liệu XML và sẽ được trình bày với những biểu tượng + và - để mở rộng và co lại mạng lưới dữ liệu XML.

Danh sách 16.9: CUSTOMERSSTYLESHEET.XSL

Page 82: Lap trinhcosodulieuvoi c-sharp_phan-3

<?xml version="1.0"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:template match="/"> <HTML> <HEAD> <TITLE>Customers</TITLE> </HEAD> <BODY> <xsl:for-each select="/NorthwindCustomers/Customers"> <p> <b>Customer:</b> <br><xsl:value-of select="CustomerID"/></br> <br><xsl:value-of select="CompanyName"/></br> <br><xsl:value-of select="PostalCode"/></br> <br><xsl:value-of select="Country"/></br> <br><xsl:value-of select="Phone"/></br> </p> </xsl:for-each> </BODY> </HTML> </xsl:template> </xsl:stylesheet>

Như bạn có thể thấy, file CustomersStylesheet.xsl chứa những thẻ HTML và những thẻ xsl. Những thẻ xsl là những chỉ dẫn chỉ định XML sẽ được thay đổi như thế nào. Bạn có thể tham chiếu file XSLT này trong một file XML ; những quy tắc trong file XSLT rồi được ứng dụng vào dữ liệu trong file XML . Bạn sẽ học cách làm điều đó như thế nào sau trong mục này. Chúng ta hãy nhìn kỹ hơn tại những hàng trong file CustomersStylesheet.xsl . File này bắt đầu với hàng sau đây, nó cho biết file sử dụng XML phiên bản 1.0 <?xml version="1.0"?> Những hàng kế tiếp là những thẻ xsl

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:template match="/">

Dòng đầu tiên sử dụng xsl: thẻ stylesheet và chỉ định không gian tên http://www.w3.org/1999/XSL/Transform sẽ được sử dụng. Dòng thứ hai sử dụng xsl: thẻ template và gán thuộc tính phù hợp tới /, nó chỉ rõ toàn bộ tài liệu XML sẽ được chọn và sử dụng bởi bộ xử lý XSLT, bắt đầu tại nút gốc. Ghi chú: Bạn có thể gán thuộctính match cho bất kỳ biểu thức XPath nào. Chẳng hạn, nếu bạn gán match tới //Customers, thì tất cả những nút Customers sẽ được chọn. Những dòng kế tiếp là những thẻ HTML, nó bắt đầu phần HTML của file, định nghĩa một đầu mục, và bắt đầu thân mục.

<HTML> <HEAD> <TITLE>Customers</TITLE>

Page 83: Lap trinhcosodulieuvoi c-sharp_phan-3

</HEAD> <BODY>

Những hàng kế tiếp là nội dung thực sự của file XSLT và sử dụng xsl: thẻ for -each để lặp qua những nút Customers:

<xsl:for-each select="/NorthwindCustomers/Customers"> <p> <b>Customer:</b> <br><xsl:value-of select="CustomerID"/></br> <br><xsl:value-of select="CompanyName"/></br> <br><xsl:value-of select="PostalCode"/></br> <br><xsl:value-of select="Country"/></br> <br><xsl:value-of select="Phone"/></br> </p> </xsl:for-each>

Còn lại dòng gần sát những phấn HTML và xsl của file:

</BODY> </HTML> </xsl:template> </xsl:stylesheet>

File XSLT chỉ chứa những quy tắc để thay đổi dữ liệu XML; chúng tôi vẫn còn cần cung cấp chính dữ liệu XML. Danh sách 16.10 cho thấy một file XML có tên CustomersUsingStylesheet.xml, chứa dữ liệu XML cho hai khách hàng. Danh sách 16.10: CUSTOMERSUSINGSTYLESHEET.XML

<?xml version="1.0"?> <?xml-stylesheet type="text/xsl" href="CustomersStylesheet.xsl"?> <NorthwindCustomers> <Customers> <CustomerID>ALFKI</CustomerID> <CompanyName>Alfreds Futterkiste</CompanyName> <PostalCode>12209</PostalCode> <Country>Germany</Country> <Phone>030-0074321</Phone> </Customers> <Customers> <CustomerID>ANATR</CustomerID> <CompanyName>Ana Trujillo Emparedados y helados</CompanyName> <PostalCode>05021</PostalCode> <Country>Mexico</Country> <Phone>(5) 555-4729</Phone> </Customers> </NorthwindCustomers>

Danh sách này đồng nhất với File Customers.xml được trình bày trước đó trong Danh sách 16.7 nhưng với sự thêm của hàng sau, nó tham chiếu file CustomersStylesheet.xsl:

<?xml-stylesheet type="text/xsl" href="CustomersStylesheet.xsl"?>

Dòng này gây ra bộ xử lý XSLT đọc và áp dụng những quy tắc trong file CustomersStylesheet.xsl lên dữ liệu XML trong file CustomersUsingStylesheet.xml . Hình 16.5 trình bày CustomersUsingStylesheet.xml hiển thị như thế nào khi xem bằng Intrenet Explorer . để xem file này, kích phải vào CustomersUsingStylesheet.xml

Page 84: Lap trinhcosodulieuvoi c-sharp_phan-3

trong Windows Explorer và chọn Open With > Internet Explorer.

Hình 16.5: xem CustomersUsing- Stylesheet.xml trong Internet Explorer Khi bạn mở CustomersUsingStylesheet.xml, Bộ xử lý XSLT của Internet Explorer mở file CustomersStylesheet.xsl và áp dụng những quy tắc trong nó vào dữ liệu XML trong CustomersUsingStylesheet.xml. Đầu ra được phát sinh bởi bộ xử lý XSLT và rồi được trình bày trong Internet Explorer. Tôi chỉ bàn đến sử dụng XSLT trong mục này. XSLT là một ngôn ngữ rất mạnh chứa đựng nhiều chức năng bạn có thể sử dụng để định dạng dữ liệu XML của bạn. Để biết chi tiết hơn, xem Mastering XSLT viết bởi Chuck White (Sybex, 2002). Bạn cũng có thể học nhiều hơn tại trang web của tập đoàn mạng toàn cầu tại www.w3.org; hãy tìm trong XSLT trong bảng mục lục. Truy cập Máy chủ phục vụ SQL sử dụng HTTP Bạn có thể truy cập Máy chủ phục vụ SQL sử dụng HTTP "Giao thức chuyển đổi siêu văn bản"(Hypertext Transfer Protocol). Nó cho phép bạn chạy những câu lệnh SQL từ một bộ duyệt. Chẳng hạn, bạn có thể chạy một phát biểu SELECT để trả lại XML, và Máy chủ phục vụ SQL sẽ trình bày những kết quả trong bộ duyệt của bạn. Bạn có thể sử dụng những phát biểu XPath để định vị dữ liệu trong XML được trả về, và sử dụng XSL stylesheets để định dạng XML được trả lại. Tôi sẽ chỉ cho bạn cách để làm tất cả những thứ này trong mục này. Cảnh báo: Bạn có thể thậm chí chạy những phát biểu INSERT, UPDATE, và DELETE - nhưng Bạn sẽ cần phải cẩn thận về việc hạn chế khả năng để chạy những kiểu phát biểu này bởi vì một người sử dụng sai lầm có thể dễ dàng phá hoại cơ sở dữ liệu của bạn. Trước khi bạn có thể truy cập máy chủ phục vụ SQL sử dụng HTTP, Bạn sẽ cần định hình sự hỗ trợ SQL XML cho IIS (Máy chủ phục vụ thông tin Internet). Định hình sự hỗ trợ SQL XML cho IIS Để định hình sự hỗ trợ SQL XML cho IIS, chọn Start > Programs > Microsoft SQL Server > Configure SQL XML Support in IIS. Điều này khởi động "Bộ quản lý thư mục thực tế IIS" (IIS Virtual Directory Management ) cho bàn điều khiển Máy chủ phục vụ SQL, như trình bày trong Hình 16.6. Bạn sử dụng bàn điều khiển này để định nghĩa một thư mục thực tế thông qua đó Bạn truy cập máy chủ phục vụ SQL qua HTTP.

Page 85: Lap trinhcosodulieuvoi c-sharp_phan-3

Hình 16.6: Quản lý thư mục thực tế IIS cho bàn điều khiển máy chủ phục vụ SQL Tiếp theo, nhấn phải trên trang web mặc định và sự chọn New > Virtual Directory từ menu sổ xuống. Bạn sẽ cần gán những thuộc tính cho thư mục ảo của bạn sử dụng New Virtual Directory Properties window (cửa sổ những thuộc tính Thư mục ảo mới) . Cửa sổ này chứa sáu thẻ, thẻ đầu tiên có tên General, bạn thường gán tên Thư mục ảo của bạn (Tên mà thông qua đó bạn truy cập máy chủ phục vụ SQL) và Đường dẫn cục bộ (Hệ thống file của Thư mục thực tế trong máy tính của bạn nơi bạn lưu trữ những file, như những file XML và XSLT). Tôi có đặt tên Thư mục Thực tế của tôi tới Northwind và Đường dẫn cục bộ của tôi tới F :\ Northwind, như trình bày trong Hình 16.7.

Hình 16.7: việc đặt tên thư mục ảo và đường dẫn cục bộ Khi bạn mở CustomersUsingStylesheet.xml, Bộ xử lý XSLT của Internet Explorer sẽ mở file CustomersStylesheet.xsl và áp dụng những quy tắc trong nó vào dữ liệu XML trong CustomersUsingStylesheet.xml. Đầu ra được phát sinh bởi bộ xử lý XSLT rồi được trình bày trong Internet Explorer.

Page 86: Lap trinhcosodulieuvoi c-sharp_phan-3

Cảnh báo: thư mục bạn chỉ định cho đường dẫn cục bộ của bạn phải đang tồn tại trong hệ thống tập tin của máy tính của bạn. Tạo ra nó sử dụng Windows Explorer, và duyệt tới thư mục này sử dụng nút browse. Tiếp theo, bạn sử dụng thẻ Security để thiết đặt những chi tiết về cách xác nhận người sử dụng khi truy nhập máy chủ phục vụ SQL như thế nào. Tôi có sử dụng tài khỏan SQL Server sa , như trình bày trong hình 16.8.

Hình 16.8: thiết đặt chi tiết thẫm quyền

Cảnh báo: Trong một hệ thống sản xuất, bạn sẽ muốn sử dụng một tài khoản có những hạn chế quyền hạn trong cơ sở dữ liệu. Chẳng hạn, bạn có lẽ sẽ muốn chỉ cho phép sự truy cập đọc tới những bảng.

Tiếp theo, bạn sử dụng thẻ Data Source để gán tới máy chủ phục vụ SQL nào mà bạn muốn sử dụng, cùng với cơ sở dữ liệu mà bạn muốn truy cập. Tôi đã chọn máy chủ phục vụ local SQL và cơ sở dữ liệu Northwind, như trong Hình 16.9.

Page 87: Lap trinhcosodulieuvoi c-sharp_phan-3

Hình 16.7: Gán Tên Thư mục ảo và đường dẫn cục bộ

Cảnh báo: thư mục bạn chỉ định cho đường dẫn địa phương của bạn phải đang tồn tại trong hệ thống tập tin của máy tính của bạn. Tạo ra nó sử dụng Windows Explorer, và duyệt tới thư mục này sử dụng nút browse.

Tiếp theo, bạn sử dụng thẻ Security để thiết đặt những chi tiết về cách xác nhận người sử dụng khi truy cập máy phục vụ SQL như thế nào. Tôi có sử dụng tài khỏan SQL server sa, như trong hình 16.8.

Hình 16.8: thiết đặt chi tiết quyền hạn Cảnh báo: Trong một hệ thống sản xuất, bạn sẽ muốn sử dụng một tài khoản có những hạn chế quyền hạn trong cơ sở dữ liệu. ví dụ bạn có lẽ sẽ muốn cho phép sự truy cập chỉ được đọc tới những bảng. Tiếp theo, bạn sử dụng thẻ Data Source để gán Máy chủ phục vụ SQL nào bạn muốn sử dụng, cùng với cơ sở dữ

Page 88: Lap trinhcosodulieuvoi c-sharp_phan-3

liệu bạn muốn truy cập. Tôi có chọn máy chủ phục vụ local SQL và cơ sở dữ liệu Northwind, như trong Hình 16.9.

Hình 16.9: thiết đặt nguồn dữ liệu Tiếp theo, bạn sử dụng thẻ Settings để chỉ định kiểu truy cập tới SQL Server bạn muốn cấp phát. chọn kiểm những hộp kiểm sau đây: Allow URL Queries (cho phép sự thực thi trực tiếp của những câu lệnh SQL), Allow Template Queries (cho phép sử dụng XML và những file XSLT truy xuất và định dạng những kết quả từ cơ sở dữ liệu), và Allow XPath Queries (cho phép sự thực thi của những truy vấn với những biểu thức XPath), như trình bày trong Hình 16.10.

Hình 16.10: thiết đặt kiểu truy nhập Cảnh báo: Trong một hệ thống sản xuất, bạn sẽ muốn hạn chế sự truy nhập để chỉ cho phép những truy vấn

Page 89: Lap trinhcosodulieuvoi c-sharp_phan-3

khuôn mẫu .Bằng cách này, những người sử dụng chỉ có thể thực thi những truy vấn được định nghĩa trong một file khuôn mẫu XML. Tiếp theo, bạn sử dụng thẻ Virtual Names để vẽ giản đồ một mô hình cơ sở dữ liệu, một thư mục template chứa những file XML và XSLT , hay một đối tượng cơ sở dữ liệu (dbobject) tới một đường dẫn liên quan với thư mục ảo của các bạn. Kích nút New và gán Virtual Name của bạn tới Templates, Kiểu của khuôn mẫu, và đường dẫn của bạn tới một danh mục con tên Templates trong thư mục Northwind của bạn, như được trình bày trong Hình 16.11. Bạn sẽ cần tạo thư mục những khuôn mẫu trước tiên.

Hình 16.11: thiết đặt cấu hình tên ảo Cảnh báo: Những danh mục con khuôn mẫu (Templates subdirectory ) mà bạn chỉ định trong đường dẫn của bạn phải đang tồn tại trong hệ thống tập tin của máy tính của bạn. Sử dụng Windows Explorer để tạo nó, và rồi duyệt tới thư mục này sử dụng nút ellipsis (...) ở bên phải của Path field (trường đường dẫn). Kích Save để tiếp tục. Bạn đừng thay đổi bất cứ thứ gì trong thẻ Advanced, nhưng cứ thoải mái nghiên cứu nó nếu bạn muốn . Kích OK để lưu những sự thiết đặt của bạn qua tất cả các thẻ. Thư mục ảo mới của bạn đã được tạo ra và sẽ xuất hiện trong IIS Virtual Directory Management (Quản lý thư mục ảo IIS cho bàn điều khiển SQL Server. Chạy những phát biểu SQL trực tiếp sử dụng một Bộ duyệt (Browser). Trong mục này, bạn sẽ học cách để chạy trực tiếp những câu lệnh SQL như thế nào sử dụng một bộ duyệt. Tôi sẽ sử dụng Internet Explorer trong những ví dụ, nhưng bạn có thể sử dụng dù bộ duyệt nào bạn muốn. Chạy những phát biểu SELECT Trong mục này, bạn sẽ thấy cách chạy một phát biểu SELECT như thế nào. Chẳng hạn, trỏ bộ duyệt của các bạn tới sự URL sau , có chứa một phát biểu SELECT dược nhúng :

http://localhost/Northwind?sql=SELECT+*+FROM+Customers+WHERE+CustomerID+IN+('ALFKI' ,'ANATR')+FOR+XML+AUTO&root=ROOT

Như bạn có thể thấy, phát biểu SELECT trong URL này truy xuất hai hàng từ bảng những khách hàng. Bộ phận đầu tiên của URL là:

http://localhost/Northwind

Nó chứa tên của máy chủ phục vụ (localhost) và thư mục ảo (Northwind). Bộ phận thứ hai của URL là:

?sql=SELECT+*+FROM+Customers+WHERE+CustomerID+IN+('ALFKI','ANATR')+FOR+XML+ AUTO&root=ROOT

Nó chứa phát biểu SELECT được nhúng. Vì URLs không cho phép những khoảng cách, bạn sử dụng những ký tự (+) thay vào đó. Tham số gốc (root) ở cuối của URL cung cấp một tên cho phần tử gốc trong XML được trả

Page 90: Lap trinhcosodulieuvoi c-sharp_phan-3

về bởi phát biểu SELECT; Tôi đã có cung cấp một tên gốc là ROOT trong ví dụ trước , nhưng bạn có thể sử dụng bất cứ tên nào bạn muốn. Hình 16.12 cho thấy kết quả của việc chạy phát biểu SELECT trong Internet Explorer.

Hình 16.12: lựa chọn những khách hàng và trình bày những kết quả Cảnh báo: Nếu bạn bỏ qua tham số root trong URL của bạn, thì bạn sẽ nhận được lỗi sau : "Only one top level element is allowed in an XML document." ( chỉ một phần tử đầu được cho phép trong một tài liệu XML.) Những khoảng cách không phải là chỉ những ký tự bạn sẽ cần để thay thế trong URL của bạn. Bảng 16.4 cho thấy một số những ký tự đặc biệt bạn có thể sử dụng trong một phát biểu SQL và sự thay thế bạn sử dụng trong URL . Bảng 16.4: những ký tự đặc biệt trong một câu lệnh SQL và những sự thay thế của chúng trong một URL Ký tự trong câu lệnh SQL Sự thay thế ở URLSpace + / %2F ? %3F % %25 # %23 & %26 Chẳng hạn, nếu bạn muốn sử dụng LIKE ' C%' trong phát biểu SELECT của bạn, thì bạn sẽ sử dụng LIKE +' C% 25', Như trình bày trong URL sau:

http://localhost/Northwind?sql=SELECT+*+FROM+Customers+WHERE+CompanyName+LIKE+'C%25 '+FOR+XML+AUTO&root=ROOT

Phát biểu SELECT trong URL này truy xuất những hàng từ bảng Customers có CompanyName bắt đầu với C. Chạy những phát biểu INSERT, UPDATE, và DELETE: Bạn có thể nhúng vào một URL những phát biểu INSERT, UPDATE, và DELETE . Ví dụ sau đây sử dụng một sự phát biểu INSERT để thêm một hàng mới vào bảng Customers:

Page 91: Lap trinhcosodulieuvoi c-sharp_phan-3

http://localhost/Northwind?sql=INSERT+INTO+Customers(CustomerID,CompanyName)+VALUES +('J9COM','J9+Company')&root=ROOT

Hình 16.13 cho thấy kết quả của việc chạy phát biểu INSERT này trong Internet Explorer.

Hình 16.13: Thêm một hàng mới vào bảng Customers Ví dụ kế tiếp sử dụng một phát biểu DELETE để loại bỏ hàng mới:

http://localhost/Northwind?sql=DELETE+FROM+Customers+WHERE+CustomerID= 'J9COM'&root=ROOT

Cảnh báo: Bạn sẽ hầu như chắc chắn muốn ngăn ngừa những người sử dụng chạy những phát biểu INSERT, UPDATE, và DELETE qua HTTP trên máy chủ phục vụ sản xuất của bạn. Bạn có thể làm điều này bởi việc cản trở những người sử dụng chạy những câu lệnh SQL trực tiếp, như được mô tả trong mục trước đây, hay bởi việc hạn chế những quyền hạn gán tới người sử dụng cơ sở dữ liệu. Bạn cũng có thể cho phép những truy nhập tới cơ sở dữ liệu chỉ được sử dụng thủ tục trữ; bạn sẽ thấy cách chạy một thủ tục lưu trữ như thế nào- sử dụng một URL trong mục kế tiếp.

Chạy những thủ tục lưu trữ: Bạn cũng có thể chạy những thủ tục lưu trữ từ một URL. Danh sách 16.11 chứa một Script tạo ra một thủ tục lưu trữ có tên CustomersFromCountry(). Thủ tục này truy xuất những hàng từ bảng Customers với một Country phù hợp với tham số @MyCountry được chuyển tới CustomersFromCountry(). Danh sách 16.11: CUSTOMERSFROMCOUNTRY.SQL

/* CustomersFromCountry.sql creates a procedure that retrieves rows from the Customers table whose Country matches the @MyCountry parameter */ CREATE PROCEDURE CustomersFromCountry @MyCountry nvarchar(15) AS SELECT * FROM Customers WHERE Country = @MyCountry FOR XML AUTO

Bạn chạy thủ tục lưu trữ này sử dụng URL sau đây:

http://localhost/Northwind?sql=EXECUTE+CustomersFromCountry+@MyCountry='UK' &root=ROOT

Hình 16.14 cho thấy kết quả của việc chạy thủ tục lưu trữ.

Page 92: Lap trinhcosodulieuvoi c-sharp_phan-3

Hình 16.14: chạy một thủ tục lưu trữ Chạy những câu lệnh SQL sử dụng một khuôn mẫu XML Bạn cũng có thể thực hiện những câu lệnh SQL sử dụng một khuôn mẫu XML, là một file XML chứa phát biểu SQL được nhúng của bạn. Danh sách 16.12 cho thấy file ví dụ có tên Customers.xml chứa một sự phát biểu SELECT được nhúng. Danh sách 16.12: những khách hàng.XML

<?xml version="1.0"?> <Northwind xmlns:sql="urn:schemas-microsoft-com:xml-sql"> <sql:query> SELECT TOP 2 CustomerID, CompanyName, City, Country FROM Customers ORDER BY CustomerID FOR XML AUTO, ELEMENTS </sql:query> </Northwind>

Ghi chú: Bạn sẽ tìm thấy file Customers.xml và những file XML và XSLT khác sử dụng trong mục tiếp theo- trong thư mục xml\Northwind\Templates . Bạn sẽ cần sao chép files này vào trong thư mục Templates bạn thiết lập trước đó cho thư mục ảo máy chủ phục vụ SQL của bạn.

Chú ý: phát biểu SELECT được đặt bên trong những thẻ sql:query và / sql:query . Thẻ Northwind ở phía ngoài là nút gốc thuộc XML. Để chạy file Customers.xml , trỏ bộ duyệt của bạn tới URL sau :

http://localhost/Northwind/Templates/Customers.xml Hình 16.15 cho thấy kết quả của việc chạy file Customers.xml trong Internet Explorer.

Page 93: Lap trinhcosodulieuvoi c-sharp_phan-3

Hình 16.15: chạy file Customers.xml Định dạng đầu ra XML sử dụng một XSL Stylesheet Như bạn sẽ học trong mục này, bạn có thể định dạng đầu ra XML được phát sinh bởi SQL máy chủ phục vụ sử dụng một XSL stylesheet. Đặc biệt, bạn sẽ thấy cách định dạng XML được chỉ ra trước đó trong Hình 16.14 như thế nào. Danh sách 16.13 trình bày một file XSL stylesheet có tên CustomersStylesheet.xsl. Danh sách 16.13: CUSTOMERSSTYLESHEET.XSL

<?xml version="1.0"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:template match="/"> <HTML> <HEAD> <TITLE>Customers</TITLE> </HEAD> <BODY> <xsl:for-each select="Northwind/Customers"> <p> <b>Customer:</b> <br><xsl:value-of select="CustomerID"/></br> <br><xsl:value-of select="CompanyName"/></br> <br><xsl:value-of select="PostalCode"/></br> <br><xsl:value-of select="Country"/></br> <br><xsl:value-of select="Phone"/></br> </p> </xsl:for-each> </BODY> </HTML> </xsl:template> </xsl:stylesheet>

Page 94: Lap trinhcosodulieuvoi c-sharp_phan-3

Chú ý: biểu thức select XPath này trong thẻ xsl: for - each được gán tới Northwind/ Customers. Northwind là nút gốc từ XML được phát sinh , và Customers là những nút con từ gốc. Bởi vậy, biểu thức XPath này lựa chọn tất cả những nút Customers từ bất kỳ XML nào phát sinh bởi máy chủ phục vụ SQL. Danh sách 16.14 cho thấy một file XML có tên CustomersUsingStylesheet.xml, mà sử dụng file CustomersStylesheet.xsl . CustomersUsingStylesheet.xml truy xuất hai hàng đầu tiên từ bảng Customers. Danh sách 16.14: CUSTOMERSUSINGSTYLESHEET.XML

<?xml version="1.0"?> <Northwind xmlns:sql="urn:schemas-microsoft-com:xml-sql" sql:xsl="CustomersStylesheet.xsl"> <sql:query> SELECT TOP 2 CustomerID, CompanyName, PostalCode, Country, Phone FROM Customers ORDER BY CustomerID FOR XML AUTO, ELEMENTS </sql:query> </Northwind>

Để chạy file CustomersUsingStylesheet.xml , trỏ bộ duyệt của bạn tới URL sau :

http://localhost/Northwind/Templates/CustomersUsingStylesheet.xml?contenttype= text/html

Chú ý: tham số contenttype ở cuối URL này được gán tới văn text/html, mà chỉ định nội dung này sẽ được trình bày như HTML. Cảnh báo: nếu bạn bỏ qua tham số contenttype, thì bạn sẽ nhận được thông báo lỗi sau: End tag 'HEAD' does not match the start tag 'META' (thẻ cuối 'HEAD' không phù hợp với thẻ đầu 'META'). Hình 16.16 cho thấy kết quả của việc chạy file CustomersUsingStylesheet.xml trong IE. Chú ý đầu ra được định dạng sử dụng những quy tắc được định nghĩa trong file CustomersStylesheet.xsl.

Hình 16.16: chạy file CustomersUsing- Stylesheet. xml Sử dụng hàm OPENXML() của máy chủ phục vụ SQL

Page 95: Lap trinhcosodulieuvoi c-sharp_phan-3

Máy chủ phục vụ SQL chứa một hàm có tên OPENXML() nó cho phép bạn đọc dữ liệu XML như thể đó là một tập hợp kết quả của những hàng. Một sử dụng của OPENXML() là đọc dữ liệu XML như những hàng, và rồi chèn những hàng này vào trong một bảng. Trong mục này, bạn sẽ khám phá cú pháp của OPENXML(). Bạn cũng sẽ thấy một ví dụ đọc dữ liệu XML chứa những chi tiết của hai khách hàng sử dụng OPENXML(), và sau đó bạn sẽ chèn hai hàng mới vào trong bảng Customers sử dụng những giá trị từ dữ liệu XML này. Cú pháp OPENXML()

OPENXML(XmlDocumentHandle int [IN], RowPattern nvarchar [IN], [Flags byte[IN]]) [WITH (SchemaDeclaration | TableName)]

VỚI: XmlDocumentHandle : chỉ rõ một int handle tới tài liệu XML của bạn. Bạn sử dụng handle này như một tham chiếu tới tài liệu XML của bạn. RowPattern: chỉ rõ một biểu thức XPath để lựa chọn dữ liệu bạn yêu cầu từ tài liệu XML của bạn. Flags: chỉ rõ một giá trị byte tùy chọn mà bạn dùng để chỉ định ánh xạ giữa dữ liệu XML của bạn và những giá trị cột cơ sở dữ liệu. Giá trị 1 chỉ báo dữ liệu XML đang được đọc của bạn - cất giữ những giá trị cột trong những thuộc tính nhúng của những nút (Danh sách 16.8, được chỉ ra trước đó, minh họa những thuộc tính nhúng); đây là mặc định. Giá trị 2 chỉ báo dữ liệu XML của bạn lưu trữ những giá trị cột như những phần tử mạng lưới riêng biệt (Danh sách 16.7, được chỉ ra trước đó, minh họa những phần tử mạng lưới). Những giá trị từ file XML của bạn sẽ được sử dụng như những giá trị cột trong những hàng tửa về bởi OPENXML(). SchemaDeclaration: chỉ rõ định nghĩa của mô hình cơ sở dữ liệu bạn muốn sử dụng để trả về những hàng như thế. Một định nghĩa ví dụ là CustomerID nvarchar(5), CompanyName nvarchar(40). Bạn sử dụng SchemaDeclaration hoặc TableName. TableName: chỉ rõ tên của bảng cơ sở dữ liệu bạn muốn sử dụng. Bạn sẽ điển hình sử dụng TableName hơn là SchemaDeclaration khi bạn đang làm việc với một bảng mà đã tồn tại trong cơ sở dữ liệu. Sử dụng OPENXML() Trước khi gọi OPENXML(), đầu tiên bạn phải gọi thủ tục sp_xml_preparedocument() . Thủ tục này phân tích tài liệu XML của bạn và chuẩn bị một bản sao của tài liệu này trong bộ nhớ. Rồi bạn sử dụng bản sao này của tài liệu XML với OPENXML(). Một khi bạn hoàn thành lệnh gọi của bạn tới OPENXML() Bạn gọi thủ tục sp_xml_removedocument() để loại bỏ tài liệu XML khỏi bộ nhớ. Ví dụ trong mục này sử dụng một thủ tục lưu trữ có tên AddCustomersXml() để đọc dữ liệu XML chứa những chi tiết của hai khách hàng- sử dụng OPENXML() và chèn hai hàng mới vào trong bảng Customers sử dụng những giá trị từ dữ liệu XML này. Danh sách 16.15 cho thấy một script có tên AddCustomersXml.sql nó tạo ra thủ tục lưu trữ AddCustomersXml() . Danh sách 16.15: ADDCUSTOMERSXML.SQL

/* AddCustomersXml.sql creates a procedure that uses OPENXML() to read customers from an XML document and then inserts them into the Customers table */ CREATE PROCEDURE AddCustomersXml @MyCustomersXmlDoc nvarchar(4000) AS - declare the XmlDocumentId handle DECLARE @XmlDocumentId int

Page 96: Lap trinhcosodulieuvoi c-sharp_phan-3

- prepare the XML document EXECUTE sp_xml_preparedocument @XmlDocumentId OUTPUT, @MyCustomersXmlDoc

- read the customers from the XML document using OPENXML() - and insert them into the Customers table INSERT INTO Customers SELECT * FROM OPENXML(@XmlDocumentId, N'/Northwind/Customers', 2) WITH Customers - remove the XML document from memory EXECUTE sp_xml_removedocument @XmlDocumentId

OPENXML() đọc XML từ tài liệu được chỉ rõ bởi handle @XmlDocumentId và trả về những hàng cho phát biểu INSERT. Những hàng này rồi được thêm vào bảng Customers bởi phát biểu INSERT. Danh sách 16.16 cho thấy một script có tên RunAddCustomers.sql - chạy thủ tục AddCustomersXml() . Danh sách 16.16: RUNADDCUSTOMERS.SQL

/* RunAddCustomersXml.sql runs the AddCustomersXml() procedure */ - define the XML document DECLARE @NewCustomers nvarchar(4000) SET @NewCustomers = N' <Northwind> <Customers> <CustomerID>T1COM</CustomerID> <CompanyName>Test 1 Company</CompanyName> </Customers> <Customers> <CustomerID>T2COM</CustomerID> <CompanyName>Test 2 Company</CompanyName> </Customers> </Northwind>' - run the AddCustomersXml() procedure EXECUTE AddCustomersXml @MyCustomersXmlDoc=@NewCustomers - display the new rows SELECT CustomerID, CompanyName FROM Customers WHERE CustomerID IN ('T1COM', 'T2COM') - delete the new rows DELETE FROM Customers WHERE CustomerID IN ('T1COM', 'T2COM')

Hình 16.17 cho thấy kết quả của việc chạy script RunAddCustomers.sql trong Query Analyzer.

Page 97: Lap trinhcosodulieuvoi c-sharp_phan-3

Hình 16.17: chạy script RunAddCustomers. sql Sử dụng một đối tượng XmlDocument để lưu trữ một tài liệu XML Bạn sử dụng một đối tượng của lớp XmlDocument để đại diện cho một tài liệu XML trong một chương trình C#. Một đối tượng XmlDocument lưu trữ những nút của tài liệu XML trong những đối tượng của lớp XmlNode. Bạn có thể, chẳng hạn, tải những hàng từ cơ sở dữ liệu vào trong một đối tượng Dataset, rồi tải một sự trình bày XML của những hàng đó vào trong một đối tượng XmlDocument. Bảng 16.5 cho thấy một số những thuộc tính XmlDocument; Bảng 16.6 cho thấy một số những phương pháp XmlDocument; và Bảng 16.7 trình bày những sự kiện XmlDocument. Bảng 16.5: những thuộc tính XmlDocument Thuộc tính Kiểu dữ liệu Mô tả Attributes XmlAttributeCollection Lấy đối tượng XmlAttributeCollection chứa những thuộc tính của

nút hiện thời. BaseURI string Lấy cơ sở URI của nút hiện thời. ChildNodes XmlNodeList Lấy tất cả những nút con của nút. DocumentElement XmlElement Lấy đối tượng XmlElement gốc cho tài liệu XML. DocumentType XmlDocumentType Lấy nút chứa khai báo DOCTYPE. FirstChild XmlNode Lấy nút con đầu tiên. HasChildNodes bool Lấy một bool cho biết liệu nút này có bất kỳ nút con nào không. Implementation XmlImplementation Lấy đối tượng XmlImplementation cho tài liệu XML. InnerText string Lấy hay gán những giá trị ràng buộc của nút và tất cả nút con của

nó. InnerXml string Lấy hay gán XML đại diện cho nút con hiện thời. IsReadOnly bool Lấy một giá trị bool cho biết liệu có phải nút hiện thời là chỉ đọc. LastChild XmlNode Lấy nút con cuối cùng. LocalName string Lấy tên địa phương của nút.

Page 98: Lap trinhcosodulieuvoi c-sharp_phan-3

Name string Lấy tên có đủ tiêu chuẩn của nút. NamespaceURI string Lấy không gian tên URI của nút. NameTable XmlNameTable Lấy đối tượng XmlNameTable có liên hệ với sự thi hành XML. NextSibling XmlNode Lấy ngay lập tức nút tiếp theo sau nút hiện thời. NodeType XmlNodeType Lấy kiểu của nút hiện thời. OuterXml string Lấy XML đại diện cho nút hiện thời và tất cả nút con của nó. OwnerDocument XmlDocument Lấy đối tượng XmlDocument mà nút hiện thời thuộc về. ParentNode XmlNode Lấy nút cha của nút hiện thời. Prefix string Lấy hay gán tiền tố namespace của nút hiện thời. PreserveWhitespace bool Lấy hay gán một giá trị bool cho biết liệu có phải khỏang trắng sẽ

được duy trì khi XML được tải hay lưu. Mặ định là false. PreviousSibling XmlNode Lấy ngay lập tức nút trước nút hiện thời. Value string Lấy hay gán giá trị của nút hiện thời XmlResolver XmlResolver Gán đối tượng XmlResolver dùng cho việc giải quyết những tài

nguyên ngoài. Bảng 16.6: những phương thức XmlDocument Phương thức Kiểu trả về Mô tả AppendChild() XmlNode Thêm nút được chỉ định vào cuối của những nút con. CloneNode() XmlNode Tạo ra một bản sao của nút. CreateAttribute() XmlAttribute Tạo ra một đối tượng XmlAttribute của tên được chỉ định. CreateCDataSection() XmlCDataSection Tạo ra một đối tượng XmlCDataSection với dữ liệu chỉ

định. CreateComment() XmlComment Tạo ra một đối tượng XmlComment với dữ liệu chỉ định. CreateDocumentFragment() XmlDocumentFragment Tạo ra một đối tượng XmlDocumentFragment với dữ liệu

chỉ định. CreateDocumentType() XmlDocumentType Tạo ra một đối tượng XmlDocumentType mới với dữ liệu

chỉ định. CreateElement() XmlElement Bị quá tải. Tạo ra một đối tượng XmlElement. CreateEntityReference() XmlEntityReference Tạo ra một đối tượng XmlEntityReference với tên được

chỉ rõ. CreateNavigator() XpathNavigator Tạo ra một đối tượng XpathNavigator mà bạn có thể dùng

để định hướng tài liệu XML. CreateNode() XmlNode Bị quá tải. Tạo ra một đối tượng XmlNode. CreateTextNode() XmlText Tạo ra một đối tượng XmlText với văn bản được chỉ rõ. CreateWhitespace() XmlWhitespace Tạo ra một đối tượng XmlWhitespace. CreateXmlDeclaration() XmlDeclaration Tạo ra một đối tượng XmlDeclaration. GetElementById() XmlElement Lấy đối tượng XmlElement với ID được chỉ rõ. GetElementsByTagName() XmlNodeList Bị quá tải. Trả về một đối tượng XmlNodeList chứa một

danh sách của tất cả các phần tử con phù hợp với tên được chỉ rõ.

GetNamespaceOfPrefix() string Tìm khai báo xmlns gần nhất với tiền tố không gian tên chỉ định trong phạm vi cho nút hiện thời, và trả về không gian tên URI.

GetPrefixOfNamespace() string Tìm khai báo xmlns gần nhất với không gian tên URI chỉ

Page 99: Lap trinhcosodulieuvoi c-sharp_phan-3

định trong phạm vi cho nút hiện thời, và trả về tiền tố không gian tên.

ImportNode() XmlNode Nhập vào một nút từ tài liệu XML khác vào trong tài liệu XML hiện thời.

InsertAfter() XmlNode Chèn nút được chỉ rõ ngay sau nút tham chiếu chỉ định. InsertBefore() XmlNode Chèn nút được chỉ rõ ngay trước nút tham chiếu chỉ định. Load() void Bị quá tải. Tải dữ liệu XML vào trong đối tượng

XmlDocument của bạn. LoadXml() void Tải tài liệu XML từ chuỗi được chỉ rõ vào trong đối tượng

XmlDocument của bạn. PrependChild() XmlNode Thêm nút được chỉ rõ vào nơi bắt đầu của những nút con. ReadNode() XmlNode Tạo ra một đối tượng XmlNode dựa vào thông tin trong

một đối tượng XmlReader được chỉ rõ. XmlReader của bạn phải được định vị trên một nút hay thuộc tính.

RemoveAll() void Loại bỏ tất cả nút con và những thuộc tính của nút hiện thời.

RemoveChild() XmlNode Loại bỏ nút con chỉ định. ReplaceChild() XmlNode Thay một nút con với nút khác. Save() void Bị quá tải. Lưu tài liệu XML tới vị trí được chỉ rõ. SelectNodes() XmlNodeList Bị quá tải. Lựa chọn một danh sách của những nút phù

hợp với biểu thức XPath được chỉ rõ. SelectSingleNode() XmlNode Bị quá tải. Lựa chọn XmlNode đầu tiên phù hợp với biểu

thức XPath được chỉ rõ. WriteContentTo() void Lưu tất cả tài liệu con của tài liệu XML vào đối tượng

XmlWriter được chỉ định. WriteTo() void Lưu tài liệu XML vào đối tượng XmlWriter chỉ định. Bảng 16.7: những sự kiện XmlDocument Sự kiện Event Handler Mô tả NodeChanging XmlNodeChangedEventHandler Khởi phát trước khi một giá trị trong một nút được thay đổi.NodeChanged XmlNodeChangedEventHandler Khởi phát sau khi một giá trị trong một nút được thay đổi. NodeInserting XmlNodeChangedEventHandler Khởi phát trước khi một nút được chèn vào. NodeInserted XmlNodeChangedEventHandler Khởi phát sau khi một nút được chèn vào. NodeRemoving XmlNodeChangedEventHandler Khởi phát trước khi một nút được loại bỏ. NodeRemoved XmlNodeChangedEventHandler Khởi phát sau khi một nút được loại bỏ. Danh sách 16.17 cho thấy một chương trình minh họa sự sử dụng một đối tượng XmlDocument. Chương trình này thực hiện những bước sau đây

1. Tạo ra một đối tượng Đataset có tên myDataSet và điền đầy nó với hai hàng đầu tiên từ bảng những khách hàng.

2. Tạo ra một đối tượng XmlDocument có tên myXmlDocument, và sau đó tải nó với XML từ myDataSet. Bạn có thể sử dụng phương thức GetXml() để trả về những hàng Customer trong myDataSet như một chuỗi chứa một tài liệu XML đầy đủ. rồi bạn có thể sử dụng chuỗi đầu ra từ GetXml() như đầu vào phương thức LoadXml() của myXmlDocument; Điều này tải myXmlDocument với tài liệu XML chứa những chi tiết khách hàng (customer details).

Page 100: Lap trinhcosodulieuvoi c-sharp_phan-3

3. Trình bày XML trong myXmlDocument sử dụng phương thức Save() , thông qua Console.Out tới phương thức Save(). Điều này dẫn đến tài liệu XML sẽ được trình bày trên màn hình.

4. Truy xuất những đối tượng XmlNode trong myXmlDocument sử dụng phương thức SelectNodes() , và sau đó trình bày văn bản được chứa đựng trong những nút con của mỗi XmlNode sử dụng thuộc tính InnerText. Bạn chuyển một biểu thức XPath tới SelectNodes() để truy xuất những nút được yêu cầu .

5. Truy xuất XmlNode cho khách hàng ANATR sử dụng phương thức SelectSingleNode() , và hiển thị văn bản chứa trong những nút con của XmlNode này. Bạn chuyển một biểu thức XPath tới SelectSingleNode() để truy xuất nút được yêu cầu.

Danh sách 16.17: USINGXMLDOCUMENT.CS

/* UsingXmlDocument.cs illustrates the use of an XmlDocument object */ using System; using System.Data; using System.Data.SqlClient; using System.Xml; class UsingXmlDocument { public static void Main() { SqlConnection mySqlConnection = new SqlConnection( "server=localhost;database=Northwind;uid=sa;pwd=sa" ); SqlCommand mySqlCommand = mySqlConnection.CreateCommand(); mySqlCommand.CommandText = "SELECT TOP 2 CustomerID, CompanyName, Country "+ "FROM Customers "+ "ORDER BY CustomerID"; SqlDataAdapter mySqlDataAdapter = new SqlDataAdapter(); mySqlDataAdapter.SelectCommand = mySqlCommand; // step 1: create a DataSet object and fill it with the top 2 rows // from the Customers table DataSet myDataSet = new DataSet(); mySqlConnection.Open(); mySqlDataAdapter.Fill(myDataSet, "Customers"); mySqlConnection.Close(); // step 2: create an XmlDocument object and load it with the XML from // the DataSet; the GetXml() method returns the rows in // myDataSet as a string containing a complete XML document; and // the LoadXml() method loads myXmlDocument with the XML document // string returned by GetXml() XmlDocument myXmlDocument = new XmlDocument(); myXmlDocument.LoadXml(myDataSet.GetXml()); // step 3: display the XML in myXmlDocument using the Save() method Console.WriteLine("Contents of myXmlDocument:"); myXmlDocument.Save(Console.Out); // step 4: retrieve the XmlNode objects in myXmlDocument using the // SelectNodes() method; you pass an XPath expression to SelectNodes()

Page 101: Lap trinhcosodulieuvoi c-sharp_phan-3

Console.WriteLine("\n\nCustomers:"); foreach (XmlNode myXmlNode in myXmlDocument.SelectNodes("/NewDataSet/Customers")) { Console.WriteLine("CustomerID = "+ myXmlNode.ChildNodes[0].InnerText); Console.WriteLine("CompanyName = "+ myXmlNode.ChildNodes[1].InnerText); Console.WriteLine("Country = "+ myXmlNode.ChildNodes[2].InnerText); } // step 5: retrieve the XmlNode for the ANATR customer using // the SelectSingleNode() method; you pass an XPath // expression to SelectSingleNode Console.WriteLine("\nRetrieving node with CustomerID of ANATR"); XmlNode myXmlNode2 = myXmlDocument.SelectSingleNode( "/NewDataSet/Customers[CustomerID=\" ANATR\"]" ); Console.WriteLine("CustomerID = "+ myXmlNode2.ChildNodes[0].InnerText); Console.WriteLine("CompanyName = "+ myXmlNode2.ChildNodes[1].InnerText); Console.WriteLine("Country = "+ myXmlNode2.ChildNodes[2].InnerText); } }

Ghi nhớ, Bạn sẽ cần thay đổi chuỗi kết nối cho đối tượng SqlConnection của bạn để kết nối tới cơ sở dữ liệu của bạn gần điểm khởi đầu của chương trình này. Đầu ra từ chương trình này như sau:

Contents of myXmlDocument: <?xml version="1.0" encoding="IBM437"?> <NewDataSet> <Customers> <CustomerID>ALFKI</CustomerID> <CompanyName>Alfreds Futterkiste</CompanyName> <Country>Germany</Country> </Customers> <Customers> <CustomerID>ANATR</CustomerID> <CompanyName>Ana Trujillo Emparedados y helados</CompanyName> <Country>Mexico</Country> </Customers> </NewDataSet> Customers: CustomerID = ALFKI CompanyName = Alfreds Futterkiste Country = Germany CustomerID = ANATR CompanyName = Ana Trujillo Emparedados y helados Country = Mexico

Page 102: Lap trinhcosodulieuvoi c-sharp_phan-3

Retrieving node with CustomerID of ANATR CustomerID = ANATR CompanyName = Ana Trujillo Emparedados y helados Country = Mexico

Sử dụng một đối tượng XmlDataDocument để lưu một tài liệu XML Trong mục trước đây, bạn xem xét cách sử dụng một đối tượng XmlDocument để lưu trữ một tài liệu XML chứa những chi tiết khách hàng truy xuất được từ một Dataset như thế nào. Điều này rất tốt, nhưng nó không phải là tuyệt nếu bạn có thể kết hợp sức mạnh của một XmlDocument với một Dataset sao? vâng , bạn có thể! Đó là nơi mà lớp XmlDataDocument đi vào. Bạn sử dụng một đối tượng của lớp XmlDataDocument để truy cập những hàng như những đối tượng XmlNode lẫn những đối tượng DataRow có quan hệ. Bạn kết hợp một Dataset với XmlDataDocument của bạn bởi việc chuyễn Dataset của bạn tới bộ khởi dựng XmlDataDocument. Một đối tượng XmlDataDocument cung cấp sự đồng bộ giữa Dataset và tài liệu XML. Chẳng hạn, nếu bạn thêm một khách hàng mới như một đối tượng XmlNode tới XmlDataDocument của bạn, Rồi khách hàng này cũng được thêm như một DataRow vào Dataset liên hệ của bạn. Tương tự, nếu bạn thêm một khách hàng mới như một DataRow vào Dataset của bạn, thì khách hàng này cũng được thêm như một đối tượng XmlNode trong tài liệu XML của XmlDataDocument. Đồng thời, nếu bạn cập nhật hay xóa một khách hàng, thì sự thay đổi này được thực hiện trong cả hai Dataset và XmlDataDocument. Lớp XmlDataDocument được bắt nguồn từ lớp XmlDocument; bởi vậy lớp XmlDataDocument thừa kế tất cả những thuộc tính chung, những phương thức và những sự kiện được trình bày trong mục trước đây cho lớp XmlDocument. Thuộc tính Dataset (Tập dữ liệu kiểu) là thuộc tính được thêm vào lớp XmlDataDocument . Nó lấy đối tượng Dataset có lưu trữ sự trình bày mối quan hệ của dữ liệu. Bạn kềt hợp một Dataset với XmlDataDocument của bạn bởi việc chuyển dataset tới bộ khởi dựng XmlDataDocument. Bảng 16.8 cho thấy những phương thức XmlDataDocument bổ sung. Bảng 16.8: những phương thức XmlDataDocument

Phương thức Kiểu trả về Mô tả GetElementFromRow() XmlElement Trả về đối tượng XmlElement có liên quan đến đối tượng DataRow được

chỉ rõ.

GetRowFromElement() DataRow Trả về đối tượng DataRow có liên quan đến đối tượng XmlElement được chỉ rõ.

Load() void Bị quá tải. Tải thông tin từ nguồn dữ kiện chỉ định vào trong đối tượng XmlDataDocument và đồng bộ hóa dữ liệu được tải với Dataset.

Danh sách 16.18 cho thấy một chương trình minh họa sự sử dụng một XmlDataDocument. Chương trình này thực hiện những bước sau đây:

1. Tạo ra một đối tượng Dataset có tên myDataSet và điền đầy nó với một DataTable có tên customersDT có chứa hai hàng đầu tiên từ bảng những khách hàng.

2. Trình bày những đối tượng DataRow trong customersDT sử dụng phương thức DisplayDataRows() , được định nghĩa gần điểm khởi đầu của chương trình.

3. Tạo ra một đối tượng XmlDataDocument có tên myXDD, chuyển MyDataSet tới bộ khởi dựng; Điều này kết hợp myDataSet với XmlDataDocument.

Page 103: Lap trinhcosodulieuvoi c-sharp_phan-3

4. Trình bày tài liệu XML trong myXDD bởi chuyển Console.Out tới phương thức Save() .

5. Thêm một DataRow khách hàng với một CustomerID là J9COM tới customersDT. 6. Truy xuất nút J9COM sử dụng phương thức GetElementFromRow() . Phương thức này chấp nhận một

DataRow như một tham số và trả về XmlNode liên hệ. 7. Gán Country của nút J9COM tới USA, đầu tiên gán thuộc tính EnforceConstraints của đối tượng

myDataSet tới false- mà bạn phải làm trước khi thực hiện bất kỳ sự thay đổi nào tới những nút. 8. Truy xuất ANATR XmlNode sử dụng SelectSingleNode(). 9. Truy xuất ANATR DataRow sử dụng GetRowFromElement(). Phương thức này chấp nhận một

XmlElement như một tham số và trả về DataRow có liên hệ. 10. Loại bỏ nút ANATR sử dụng RemoveAll(). 11. Hiển thị tài liệu XML trong myXDD sử dụng Save(). 12. Hiển thị những đối tượng DataRow trong customersDT sử dụng DisplayDataRows().

Danh sách 16.18: USINGXMLDATADOCUMENT.CS

/* UsingXmlDataDocument.cs illustrates how to use an XmlDataDocument object */ using System; using System.Data; using System.Data.SqlClient; using System.Xml; class UsingXmlDataDocument { public static void DisplayDataRows(DataTable myDataTable) { Console.WriteLine("\n\nCustomer DataRow objects in customersDT:"); foreach (DataRow myDataRow in myDataTable.Rows) { foreach (DataColumn myDataColumn in myDataTable.Columns) { Console.WriteLine(myDataColumn + "= "+ myDataRow[myDataColumn]); } } } public static void Main() { SqlConnection mySqlConnection = new SqlConnection( "server=localhost;database=Northwind;uid=sa;pwd=sa" ); SqlCommand mySqlCommand = mySqlConnection.CreateCommand(); mySqlCommand.CommandText = "SELECT TOP 2 CustomerID, CompanyName, Country "+ "FROM Customers "+ "ORDER BY CustomerID"; SqlDataAdapter mySqlDataAdapter = new SqlDataAdapter();

Page 104: Lap trinhcosodulieuvoi c-sharp_phan-3

mySqlDataAdapter.SelectCommand = mySqlCommand; // step 1: create a DataSet object and fill it with the top 2 rows // from the Customers table DataSet myDataSet = new DataSet(); mySqlConnection.Open(); mySqlDataAdapter.Fill(myDataSet, "Customers"); mySqlConnection.Close(); DataTable customersDT = myDataSet.Tables["Customers"]; // step 2: display the DataRow objects in customersDT using // DisplayDataRows() DisplayDataRows(customersDT); // step 3: create an XmlDataDocument object, passing myDataSet // to the constructor; this associates myDataSet with the // XmlDataDocument XmlDataDocument myXDD = new XmlDataDocument(myDataSet); // step 4: display the XML document in myXDD Console.WriteLine("\nXML document in myXDD:"); myXDD.Save(Console.Out); // step 5: add a customer DataRow to customersDT with a CustomerID // of J9COM Console.WriteLine("\n\nAdding new DataRow to customersDT with CustomerID of J9COM"); DataRow myDataRow = customersDT.NewRow(); myDataRow["CustomerID"] = "J9COM"; myDataRow["CompanyName"] = "J9 Company"; myDataRow["Country"] = "UK"; customersDT.Rows.Add(myDataRow); // step 6: retrieve the J9COM node using GetElementFromRow() Console.WriteLine("\nRetrieving J9COM node using GetElementFromRow()"); XmlNode myXmlNode = myXDD.GetElementFromRow(myDataRow); Console.WriteLine("CustomerID = "+ myXmlNode.ChildNodes[0].InnerText); Console.WriteLine("CompanyName = "+ myXmlNode.ChildNodes[1].InnerText); Console.WriteLine("Country = "+ myXmlNode.ChildNodes[2].InnerText); // step 7: set J9COM node's Country to USA, first setting // EnforceConstraints to false Console.WriteLine("\nSetting J9COM node's Country to USA"); myDataSet.EnforceConstraints = false; myXmlNode.ChildNodes[2].InnerText = "USA"; // step 8: retrieve the ANATR XmlNode using SelectSingleNode() Console.WriteLine("\nRetrieving ANATR node using SelectSingleNode()"); myXmlNode = myXDD.SelectSingleNode( "/NewDataSet/Customers[CustomerID=\" ANATR\"]" ); // step 9: retrieve the ANATR DataRow using GetRowFromElement() Console.WriteLine("\nRetrieving ANATR DataRow using GetRowFromElement()"); myDataRow = myXDD.GetRowFromElement((XmlElement) myXmlNode); foreach (DataColumn myDataColumn in customersDT.Columns)

Page 105: Lap trinhcosodulieuvoi c-sharp_phan-3

{ Console.WriteLine(myDataColumn + "= "+ myDataRow[myDataColumn]); } // step 10: remove the ANATR node using RemoveAll() Console.WriteLine("\nRemoving ANATR node"); myXmlNode.RemoveAll(); // step 11: display the XML document in myXDD using Save() Console.WriteLine("\nXML document in myXDD:"); myXDD.Save(Console.Out); // step 12: display the DataRow objects in customersDT using // DisplayDataRows() DisplayDataRows(customersDT); } }

Đầu ra từ chương trình này như sau: Customer DataRow objects in customersDT: CustomerID = ALFKI CompanyName = Alfreds Futterkiste Country = Germany CustomerID = ANATR CompanyName = Ana Trujillo Emparedados y helados Country = Mexico XML document in myXDD: <?xml version="1.0" encoding="IBM437"?> <NewDataSet> <Customers> <CustomerID>ALFKI</CustomerID> <CompanyName>Alfreds Futterkiste</CompanyName> <Country>Germany</Country> </Customers> <Customers> <CustomerID>ANATR</CustomerID> <CompanyName>Ana Trujillo Emparedados y helados</CompanyName> <Country>Mexico</Country> </Customers> </NewDataSet> Thêm DataRow mới vào customersDT với CustomerID J9COM Retrieving J9COM node using GetElementFromRow() CustomerID = J9COM CompanyName = J9 Company Country = UK Setting J9COM node's Country to USA Retrieving ANATR node using SelectSingleNode() Retrieving ANATR DataRow using GetRowFromElement() CustomerID = ANATR

Page 106: Lap trinhcosodulieuvoi c-sharp_phan-3

CompanyName = Ana Trujillo Emparedados y helados Country = Mexico Removing ANATR node XML document in myXDD: <?xml version="1.0" encoding="IBM437"?> <NewDataSet> <Customers> <CustomerID>ALFKI</CustomerID> <CompanyName>Alfreds Futterkiste</CompanyName> <Country>Germany</Country> </Customers> <Customers> </Customers> <Customers> <CustomerID>J9COM</CustomerID> <CompanyName>J9 Company</CompanyName> <Country>USA</Country> </Customers> </NewDataSet> Customer DataRow objects in customersDT: CustomerID = ALFKI CompanyName = Alfreds Futterkiste Country = Germany CustomerID = CompanyName = Country = CustomerID = J9COM CompanyName = J9 Company Country = USA

Tóm lược Trong chương này, bạn đã học về sự hỗ trợ XML rộng lớn của máy chủ phục vụ SQL. Bạn cũng thấy cách lưu trữ XML ở một chương trình C# sử dụng những đối tượng XmlDocument và XmlDataDocument như thế nào. Máy chủ phục vụ SQL mở rộng phát biểu SELECT để cho phép bạn truy vấn sở dữ liệu và lấy về những kết quả như XML. Đặc biệt, bạn có thể thêm một mệnh đề XML vào cuối của một phát biểu SELECT, chỉ rõ Máy chủ phục vụ SQL sẽ trả về những kết quả như XML. Bạn khảo sát Đường dẫn ngôn ngữ đánh dấu mở rộng (XPath) và sự Biến đổi ngôn ngữ Stylesheet mở rộng (XSLT). XPath là một ngôn ngữ cho phép bạn tìm kiếm và dẫn hướng một tài liệu XML sử dụng những biểu thức. XML là một cách ưu việt để trình bày dữ liệu trong một định dạng linh động, nhưng XML không chứa đựng thông tin về việc làm sao để định dạng dữ liệu này cho sự hiển thị. XSLT cho phép bạn kiểm soát việc định dạng của dữ liệu XML, và có thể dùng để thay đổi dữ liệu XML tới một định dạng thích hợp cho sự hiển thị. Bạn có thể truy cập máy chủ phục vụ SQL sử dụng HTTP (Giao thức chuyển đổi Siêu văn bản). Điều này cho phép bạn chạy những câu lệnh SQL từ một bộ duyệt; chẳng hạn, bạn có thể chạy một phát biểu SELECT mà trả về XML, và máy chủ phục vụ SQL sẽ trình bày những kết quả trong bộ duyệt của bạn. Bạn có thể sử dụng những phát biểu XPath để định vị dữ liệu trong XML được trả về, và sử dụng XSLT stylesheets để định dạng XML được trả về. Máy chủ phục vụ SQL chứa một hàm có tên OPENXML() nó cho phép bạn đọc dữ liệu XML như thể nó là một tập hợp kết quả của những hàng. Một sử dụng của OPENXML() là đọc dữ liệu XML như những hàng và sau đó chèn những hàng đó vào trong một bảng.

Page 107: Lap trinhcosodulieuvoi c-sharp_phan-3

Bạn sử dụng một đối tượng của lớp XmlDocument để đại diện cho một tài liệu XML trong một chương trình C#. Một đối tượng XmlDocument lưu trữ những nút của tài liệu XML trong những đối tượng của lớp XmlNode. Bạn có thể, chẳng hạn, tải những hàng từ cơ sở dữ liệu vào trong một Dataset, và rồi tải một sự trình bày XML của những hàng đó vào trong một đối tượng XmlDocument. Bạn sử dụng một đối tượng của lớp XmlDataDocument để truy cập những hàng như cả những đối tượng XmlNode lẫn những đối tượng DataRow có quan hệ. Bạn kết hợp một Dataset với XmlDataDocument của bạn bởi việc chuyển Dataset của bạn tới bộ khởi dựng XmlDataDocument. Một đối tượng XmlDataDocument cung cấp sự đồng bộ giữa Dataset và tài liệu XML. Chẳng hạn, nếu bạn thêm một khách hàng mới như một đối tượng XmlNode tới XmlDataDocument của bạn , thì khách hàng này cũng được thêm như một DataRow vào Dataset liên hệ của bạn. Trong chương kế tiếp, bạn sẽ học về những dịch vụ mạng . @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ Chương 17: những dịch vụ Mạng Tổng quan Một dịch vụ mạng là một thành phần phần mềm mà bạn có thể duyệt qua Mạng, và một trong số những tính năng của .NET là khả năng dễ dàng tạo ra Mạng dịch vụ. Những công ty có thể tạo ra những dịch vụ Mạng để cho phép sự tương tác với khách hàng. Chẳng hạn, một công ty tàu biển tạo ra một dịch vụ mạng cho phép những công ty khác gởi dến một tài liệu XML vào mạng có chứa một danh mục hàng hóa cần cung cấp. Công ty tàu biển có thể chấp nhận file này và hoạch định một đầu đọc những tiết mục đó, và trả lại một tài liệu XML từ dịch vụ mạng chứa một danh sách của những con số theo dõi cho mỗi tiết mục sẽ được cung cấp. Vì những dịch vụ mạng nhận và trả về dữ liệu trong form của những tài liệu XML, những dịch vụ mạng thực sự là nền tảng độc lập . Chẳng hạn, bạn có thể có một dịch vụ mạng viết với C# - giao dịch với một dịch vụ mạng khác viết bằng Java, thông qua dữ liệu trong form của những tài liệu XML. Trong chương này, bạn sẽ thấy cách tạo ra một dịch vụ mạng sử dụng VS .NET và sử dụng nó trong một ứng dụng Windows như thế nào . Bạn cũng sẽ thấy cách đăng ký một dịch vụ mạng để những tổ chức khác có thể sử dụng dịch vụ của bạn. Về phạm vi toàn diện của những dịch vụ mạng, xem .NET Web Services Solutions by Kris Jamsa (Sybex, 2003). Mục nổi bật trong Chương này:

Tạo ra một dịch vụ Mạng

Xem một file WSDL và kiểm tra một dịch vụ Mạng

Sử dụng một dịch vụ Mạng

Đăng ký một dịch vụ Mạng Tạo ra một dịch vụ Mạng Trong mục này bạn sẽ tạo ra một dịch vụ Mạng chứa một phương thức trả về một Dataset chứa những hàng từ bảng những khách hàng.

Page 108: Lap trinhcosodulieuvoi c-sharp_phan-3

Khởi động VS .NET và chọn File New Project. Trong hộp thoại New Project , chọn Visual C# Projects trong ô Project Types ở bên trái, và chọn ASP.NET Web Service trong ô Templates bên phải. Nhập vào http: // Localhost/ NorthwindWebService trong trường Định vị (Location field)- xem Hình 17.1. Kích OK để tiếp tục.

Hình 17.1: Tạo ra một dịch vụ Mạng trong VS .NET

Ghi nhớ: nếu bạn có cài đặt IIS trên một máy tính khác với máy địa phương của bạn, rồi thay thế localhost với tên của máy tính từ xa của bạn trong Location field.

Sau khi VS .NET tạo ra dự án mới, mở Solution Explorer và xóa file Service1.asmx từ dự án của bạn; tiếp theo bạn sẽ thêm file .asmx của mình, và thật dễ dàng , đơn giản là xóa file ban đầu Service1.asmx . Chọn Project Add Web Service, và nhập vào Customers.asmx trong trường tên (Name field) của hộp thoại Add New Item (xem Hình 17.2). Kích Open để tiếp tục. VS .NET thêm một file với tên Customers.asmx tới dự án của bạn.

Hình 17.2: việc thêm một dịch vụ Mạng mới Chọn View Code để xem Mã C# trong file Customers.asmx.cs . Danh sách 17.1 trình bày file ví dụ Customers.asmx.cs. Danh sách 17.1: Customers.asmx.cs

using System; using System.Collections; using System.ComponentModel; using System.Data;

Page 109: Lap trinhcosodulieuvoi c-sharp_phan-3

using System.Diagnostics; using System.Web; using System.Web.Services; namespace NorthwindWebService { /// <summary> /// Summary description for Customers. /// </summary> /// [WebService(Namespace="http://DbProgramming/NorthwindWebService")] public class Customers : System.Web.Services.WebService { public Customers() {

//CODEGEN: lệnh gọi này được yêu cầu bởi ASP.NET Web Services Designer InitializeComponent(); } #region Component Designer generated code //Required by the Web Services Designer private IContainer components = null; /// <summary> /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// </summary> private void InitializeComponent() { } /// <summary> /// Clean up any resources being used. /// </summary> protected override void Dispose(bool disposing) { if(disposing && components != null) { components.Dispose(); } base.Dispose(disposing); } #endregion // WEB SERVICE EXAMPLE // The HelloWorld() example service returns the string Hello World // To build, uncomment the following lines then save and build the project // To test this web service, press F5 // [WebMethod] // public string HelloWorld() // { // return "Hello World"; // }

Page 110: Lap trinhcosodulieuvoi c-sharp_phan-3

} Chú ý : lớp Customers được dẫn xuất từ lớp System.Web.Services.WebService . Lớp WebService, chỉ định rằng những lớp Customers hình thành bộ phận của một dịch vụ Mạng

Gần cuối của Danh sách 1.1, bạn sẽ chú ý một phương thức có tên HelloWorld() đã được ngắt thành chú thích ở ngoài. mã này chỉ bạn cách để viết một phương thức sẽ được trưng bày bởi dịch vụ mạng của bạn. Bạn sẽ chú ý một dòng chứa [ WebMethod] được đặt trước phương thức, nó cho biết phương thức sẽ được trình bày bởi dịch vụ mạng. Tất nhiên, Vì phương thức HelloWorld() đã được chuyển thành chú thích, phương thức sẽ không được biên tập và do đó không thật sự được trình bày bởi dịch vụ mạng. Thay thế phương thức ví dụ HelloWorld() trong mã của bạn với phương thức RetrieveCustomers() được trình bày trong Danh sách 17.2. RetrieveCustomers() kết nối tới cơ sở dữ liệu Northwind và trả về một Dataset chứa những hàng từ bảng những khách hàng. Bạn gởi một mệnh đề WHERE tới phương thức RetrieveCustomers() trong tham số whereClause; mệnh đề WHERE này rồi được sử dụng trong phát biểu SELECT để giới hạn những hàng được truy xuất từ bảng những khách hàng. Danh sách 17.2: CUSTOMERSWEBSERVICE.CS

[WebMethod] public DataSet RetrieveCustomers(string whereClause) { SqlConnection mySqlConnection = new SqlConnection("server=localhost;database=Northwind;uid=sa;pwd=sa"); string selectString = "SELECT CustomerID, CompanyName, Country "+ "FROM Customers "+ "WHERE "+ whereClause; SqlCommand mySqlCommand = mySqlConnection.CreateCommand(); mySqlCommand.CommandText = selectString; SqlDataAdapter mySqlDataAdapter = new SqlDataAdapter(); mySqlDataAdapter.SelectCommand = mySqlCommand; DataSet myDataSet = new DataSet(); mySqlConnection.Open(); mySqlDataAdapter.Fill(myDataSet, "Customers"); mySqlConnection.Close(); return myDataSet; }

Ghi chú Bạn sẽ cần thay đổi chuỗi được sử dụng để tạo ra đối tượng mySqlConnection trong mã của bạn để kết nối tới cơ sở dữ liệu Northwind của bạn.

Bởi vì mã sử dụng những lớp trong không gian tên System.Data.SqlClient, Bạn cũng sẽ cần thêm hàng sau đây gần đoạn đầu của file Customers.asmx.cs của bạn :

using System.Data.SqlClient; Theo mặc định, một dịch vụ mạng sử dụng một namespace là http: // tempuri.org, và bạn cần phải thay đổi nó thành URL được dùng bởi tổ chức của bạn. Những ví dụ sau gán namespace cho dịch vụ mạng tới http: // DbProgramming/ NorthwindWebService:

[WebService(Namespace="http://DbProgramming/NorthwindWebService")] public class Customers : System.Web.Services.WebService

Chú ý bạn gán Namespace trong một dòng được đặt trước lớp Customers. Tiếp tục và thêm một hàng tương tự như cái trước đây vào mã của mình. Xây dựng dịch vụ mạng của bạn bởi chọn Build � Build Solution.

Page 111: Lap trinhcosodulieuvoi c-sharp_phan-3

Thế là xong ! Bạn đã xây dựng dịch vụ mạng của bạn.

Xem một file WSDL và kiểm tra một dịch vụ mạng WSDL thay thế cho Ngôn ngữ mô tả những dịch vụ mang, và một file WSDL chứa một sự mô tả đầy đủ dịch vụ mạng của bạn, bao gồm thông tin yêu cầu để gọi những phương thức của dịch vụ của bạn. Một file WSDL được viết trong XML và chỉ rõ thông tin sau đây

■ Những phương thức dịch vụ mạng ■ Những kiểu dữ liệu được dùng bởi những phương thức ■ Những định dạng thông báo yêu cầu và đáp lại cho sự truyền thông với những phương thức

Ghi chú Cho thông tin toàn diện về WSDL, viếng thăm www.w3.org / TR/ wsdl.

Bạn truy cập dịch vụ mạng của bạn bằng cách trỏ bộ duyệt của bạn tới URL sau đây:

http://localhost/NorthwindWebService/Customers.asmx Như bạn có thể thấy từ Hình 17.3, trang kết quả được trình bày trong bộ duyệt của bạn chứa hai mối liên kết có tên Service Description (sự mô tả dịch vụ) và Retrieve Customers (truy xuất những khách hàng).

Hình 17.3: Truy cập dịch vụ mạng Ghi chú Bạn cũng có thể truy cập dịch vụ mạng của bạn bởi việc nhấp phải trên file Customers.asmx trong cửa sổ Solution Explorer trong VS .NET và chọn Set As Start Page từ thực đơn bật ra. rồi bạn chọn Debug � Start Without Debugging để kiểm tra dịch vụ của bạn. VS .NET sẽ khởi động Internet Explorer và hiển thị giống như trang thử chạy bạn thấy trong Hình 17.3.

Xem File WSDL của dịch vụ mạng Nếu bạn kích mối liên kết Service Description, bạn sẽ nhìn thấy phần mô tả của dịch vụ mạng của bạn trong form của một file WSDL, được trình bày trong Danh sách 17.3. Chú ý file WSDL này được viết trong XML và chứa chi tiết về cách gọi những phương thức được trình bày bởi dịch vụ mạng ví dụ như thế nào. File WSDL cũng chứa những kiểu dữ liệu của những tham số được dùng và những lệnh gọi mà bạn có thể thực hiện tới những phương thức của bạn .

Page 112: Lap trinhcosodulieuvoi c-sharp_phan-3

Danh sách 17.3: File WSDL dịch vụ mạng

<?xml version="1.0" encoding="utf-8"?> <definitions xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:s="http://www.w3.org/2001/XMLSchema" xmlns:s0="http://DbProgramming/NorthwindWebService" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:tm="http://microsoft.com/wsdl/mime/textMatching/" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" targetNamespace="http://DbProgramming/NorthwindWebService" xmlns="http://schemas.xmlsoap.org/wsdl/"> <types> <s:schema elementFormDefault="qualified" targetNamespace="http://DbProgramming/NorthwindWebService"> <s:import namespace="http://www.w3.org/2001/XMLSchema" /> <s:element name="RetrieveCustomers"> <s:complexType> <s:sequence> <s:element minOccurs="0" maxOccurs="1" name="whereClause" type="s:string" /> </s:sequence> </s:complexType> </s:element> <s:element name="RetrieveCustomersResponse"> <s:complexType> <s:sequence> <s:element minOccurs="0" maxOccurs="1" name="RetrieveCustomersResult"> <s:complexType> <s:sequence> <s:element ref="s:schema" /> <s:any /> </s:sequence> </s:complexType> </s:element> </s:sequence> </s:complexType> </s:element> <s:element name="DataSet" nillable="true"> <s:complexType> <s:sequence> <s:element ref="s:schema" /> <s:any /> </s:sequence> </s:complexType> </s:element> </s:schema> </types> <message name="RetrieveCustomersSoapIn"> <part name="parameters" element="s0:RetrieveCustomers" /> </message> <message name="RetrieveCustomersSoapOut"> <part name="parameters" element="s0:RetrieveCustomersResponse" /> </message> <message name="RetrieveCustomersHttpGetIn">

Page 113: Lap trinhcosodulieuvoi c-sharp_phan-3

<part name="whereClause" type="s:string" /> </message> <message name="RetrieveCustomersHttpGetOut"> <part name="Body" element="s0:DataSet" /> </message> <message name="RetrieveCustomersHttpPostIn"> <part name="whereClause" type="s:string" /> </message> <message name="RetrieveCustomersHttpPostOut"> <part name="Body" element="s0:DataSet" /> </message> <portType name="CustomersSoap"> <operation name="RetrieveCustomers"> <input message="s0:RetrieveCustomersSoapIn" /> <output message="s0:RetrieveCustomersSoapOut" /> </operation> </portType> <portType name="CustomersHttpGet"> <operation name="RetrieveCustomers"> <input message="s0:RetrieveCustomersHttpGetIn" /> <output message="s0:RetrieveCustomersHttpGetOut" /> </operation> </portType> <portType name="CustomersHttpPost"> <operation name="RetrieveCustomers"> <input message="s0:RetrieveCustomersHttpPostIn" /> <output message="s0:RetrieveCustomersHttpPostOut" /> </operation> </portType> <binding name="CustomersSoap" type="s0:CustomersSoap"> <soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document" /> <operation name="RetrieveCustomers"> <soap:operation soapAction="http://DbProgramming/NorthwindWebService/RetrieveCustomers" style="document" /> <input> <soap:body use="literal" /> </input> <output> <soap:body use="literal" /> </output> </operation> </binding> <binding name="CustomersHttpGet" type="s0:CustomersHttpGet"> <http:binding verb="GET" /> <operation name="RetrieveCustomers"> <http:operation location="/RetrieveCustomers" /> <input> <http:urlEncoded /> </input> <output> <mime:mimeXml part="Body" /> </output> </operation> </binding>

Page 114: Lap trinhcosodulieuvoi c-sharp_phan-3

<binding name="CustomersHttpPost" type="s0:CustomersHttpPost"> <http:binding verb="POST" /> <operation name="RetrieveCustomers"> <http:operation location="/RetrieveCustomers" /> <input> <mime:content type="application/x-www-form-urlencoded" /> </input> <output> <mime:mimeXml part="Body" /> </output> </operation> </binding> <service name="Customers"> <port name="CustomersSoap" binding="s0:CustomersSoap"> <soap:address location="http://localhost/NorthwindWebService/Customers.asmx" /> </port> <port name="CustomersHttpGet" binding="s0:CustomersHttpGet"> <http:address location="http://localhost/NorthwindWebService/Customers.asmx" /> </port> <port name="CustomersHttpPost" binding="s0:CustomersHttpPost"> <http:address location="http://localhost/NorthwindWebService/Customers.asmx" /> </port> </service> </definitions>

Tiếp theo, bạn sẽ thấy cách kiểm tra dịch vụ mạng của bạn như thế nào.

Kiểm tra một dịch vụ mạng Để kiểm tra dịch vụ mạng của bạn, trỏ bộ duyệt của bạn tới URL sau :

http://localhost/NorthwindWebService/Customers.asmx Kích liên kết Retrieve Customers. Bộ duyệt của bạn trình bày một trang ( xem Hình 17.4) mà bạn có thể dùng để thử phương thức RetrieveCustomers() được trình bày bởi dịch vụ mạng của bạn.

Page 115: Lap trinhcosodulieuvoi c-sharp_phan-3

Hình 17.4: trang thử nghiệm dịch vụ Mạng Trang thử nghiệm chứa một hộp văn bản với một nhãn là whereClause nơi mà bạn có thể nhập vào những giá trị cho tham số whereClause của phương thức RetrieveCustomers() của bạn. Văn bản bạn nhập vào cho whereClause được chuyển cho phương thức RetrieveCustomers() khi bạn kích nút Invoke trên mặt trang. Nhập vào văn bản sau như whereClause của bạn:

CustomerID='ALFKI' Kích nút Invoke để chạy phương thức RetrieveCustomers().Với whereClause này, phương thức RetrieveCustomers() trả về một Dataset với một DataTable chứa một hàng từ bảng những khách hàng với một CustomerID là ALFKI, như trình bày trong Hình 17.5. Chú ý “lượng bằng nhau” equals (=) và những ký tự (') “trích dẫn đơn” trong giá trị tham số whereClause của URL đã được chuyển đổi thành những mã % 3D và % 27 tương ứng.

Page 116: Lap trinhcosodulieuvoi c-sharp_phan-3

Hình 17.5: Chạy phương thức RetrieveCustomers() với một whereClause là CustomerID= ' ALFKI' Như bạn có thể thấy từ Hình 17.5, Dataset được trả về như một tài liệu XML. Bạn có thể sử dụng XML này trong những chương trình máy khách của bạn mà sử dụng dịch vụ mạng. Bạn sẽ thấy cách để viết một chương trình máy khách như thế nào trong mục kế tiếp. Chúng ta hãy xem xét ví dụ khác; nhập vào chuỗi sau đây như whereClause của bạn và kích nút Invoke:

CustomerID IS NOT NULL

Điều này gây cho phương thức RetrieveCustomers() trả lại một Dataset với một DataTable chứa tất cả những hàng từ bảng những khách hàng ( xem Hình 17.6). Chú ý những ký tự khoảng cách trong giá trị tham số whereClause đã được chuyển đổi thành những ký tự cộng (+). Bạn sẽ cần cuộn xuống trang để xem những khách hàng khác.

Page 117: Lap trinhcosodulieuvoi c-sharp_phan-3

Hình 17.6: Chạy phương thức RetrieveCustomers() với một whereClause của CustomerID không phải NULL Tiếp theo, bạn sẽ thấy cách sử dụng dịch vụ mạng của bạn trong một ứng dụng Windows như thế nào.

Sử dụng một dịch vụ mạng Trong mục này bạn sẽ thấy cách sử dụng một dịch vụ mạng như thế nào trong một ứng dụng Windows. Khởi động VS .NET và chọn File � New � Project. Tạo ra một ứng dụng Windows mới có tên UseWebServiceInWindows. Kéo một DataGrid, TextBox, và điều khiển Nút tới form của bạn. Gán thuộc tính Name của DataGrid của bạn tới customersDataGrid. Gán thuộc tính Name của TextBox của bạn tới whereClauseTextBox, và loại bỏ văn bản textBox1 từ thuộc tính Text. gán thuộc tính Name của Nút của bạn tới getCustomersButton, và gán thuộc tính Text tới Get Customers. Những điều khiển này được trình bày trong Hình 17.7.

Page 118: Lap trinhcosodulieuvoi c-sharp_phan-3

Hình 17.7: Form với những điều khiển Mở cửa sổ Solution Explorer và nhấp phải nút References. Chọn Add Web References từ thực đơn bật ra. Việc này hiển thị hộp thoại Add Web Reference , cho phép bạn tìm kiếm những dịch vụ Mạng. Nhập vào URL sau đây vào hộp Address, và nhấn phím Enter trên bàn phím của bạn: http://localhost/NorthwindWebService/Customers.asmx Ghi chú: Nếu dịch vụ mạng của bạn không được triển khai trên máy tính địa phương, thì thay thế localhost với tên của máy tính từ xa của bạn. Dịch vụ Mạng của bạn sẽ được định vị và một trang thử được trình bày (xem Hình 17.8).

Hình 17.8: Dịch vụ Mạng Northwind Bạn có thể xem file WSDL thuộc dịch vụ Mạng của bạn bởi việc kích liên kết Service Description, và Bạn có thể kiểm tra dịch vụ mạng của bạn bởi việc kích liên kết Retrieve Customers . Kích nút Add Reference để thêm tham chiếu đến dịch vụ Mạng của bạn vào dự án của bạn và tiếp tục. Bạn có thể thấy tham chiếu mới trong cửa sổ Solution Explorer (xem Hình 17.9).

Page 119: Lap trinhcosodulieuvoi c-sharp_phan-3

Hình 17.9: Tham chiếu Mạng mới trong Solution Explorer Nhấn đúp nút trên form của bạn để mở cửa sổ biên tập mã, và thêm mã sau đây vào phương thức click Nút của bạn :

localhost.Customers myCustomersService = new localhost.Customers(); customersDataGrid.DataSource = myCustomersService.RetrieveCustomers(whereClauseTextBox.Text); customersDataGrid.DataMember = "Customers";

Ghi nhớ : xin nhắc lại một lần nữa, nếu dịch vụ Mạng của bạn không được triển khai trên máy tính địa phương, thì thay thế localhost trong mã này với tên của máy tính từ xa của bạn.

Mã này tạo ra một đối tượng có tên myCustomersService để gọi dịch vụ Mạng của bạn, và trình bày những kết quả được trả về từ phương thức RetrieveCustomers() trong customersDataGrid. Biên tập và chạy ứng dụng Windows của bạn bởi chọn Debug Start Without Debugging. Nhập CustomerID= ' ALFKI' vào trong hộp textbox, và kích nút Get Customers ; những kết quả được truy xuất được trình bày trong Hình 17.10.

Hình 17.10: Form đang chạy Tiếp theo, bạn sẽ thấy cách đăng ký dịch vụ Mạng của bạn như thế nào

Page 120: Lap trinhcosodulieuvoi c-sharp_phan-3

Đăng ký một dịch vụ Mạng Trong mục này, bạn sẽ thấy cách đăng ký một dịch vụ Mạng sử dụng những dịch vụ mạng của Microsoft như: Universal Description, Discovery, and Integration (UDDI). Bạn có thể hiểu UDDI như một thư mục phân phối của những dịch vụ Mạng mà bạn có thể thường đăng ký và định vị những dịch vụ mạng được thành lập bởi những tổ chức. UDDI là một tiêu chuẩn công nghiệp được phát triển bởi Microsoft, IBM, Sun Microsystems, và những công ty phần mềm và phần cứng khác.

Ghi chú: Về thông tin toàn diện của UDDI, thăm www.uddi.org và uddi.microsoft.com. Một khi bạn đăng ký dịch vụ Mạng của bạn, bất cứ ai cũng có thể sử dụng dịch vụ của bạn như một thành phần phần mềm trong hệ thống của mình; tương tự, bạn có thể sử dụng những dịch vụ Mạng của người khác trong hệ thống của bạn. Bạn có thể thậm chí đăng ký những dịch vụ Mạng cho intranet của tổ chức của mình và xây dựng một hệ thống bên trong tạo nên từ những dịch vụ Mạng được viết bên trong. Trong mục này, bạn sẽ đăng ký NorthwindWebService bạn tạo ra trước đó trong chương này. Để làm điều này, thực hiện theo những bước sau: Từ VS .NET, kích thẻ "Start Page ", kích liên kết "XML Web Services" , và kích liên kết "Register Your XML Web Service Today" (xem Hình 17.11). Bạn có thể tìm kiếm những dịch vụ Mạng sử dụng "Find A Service page".

Hình 17.11: những trang dịch vụ Mạng XML Từ trang đăng ký dịch vụ Mạng UDDI, bạn có thể đăng ký dịch vụ mạng của bạn hoặc với sự thử hoặc môi trường sản xuất.Vì dịch vụ mạng của bạn là chỉ là một ví dụ, kích nút kiểm UDDI Test Environment và kích nút Submit (xem Hình 17.12). Nếu bạn tạo ra một dịch vụ mạng hữu ích thực sự và bạn tin tưởng những tổ chức khác sẽ muốn sử dụng, bạn có thể đăng ký dịch vụ mạng của bạn với môi trường sản xuất.

Page 121: Lap trinhcosodulieuvoi c-sharp_phan-3

Hình 17.12: Trang đăng ký dịch vụ mạng UDDI Đọc văn bản trong trang UDDI Business Registry Node (xem Hình 17.13). Trang này giải thích những bước kế tiếp bạn phải theo . Kích nút Sign In khi bạn đã hòan tất việc đọc văn bản.

Hình 17.13: trang Nút Nơi đăng ký Doanh nghiệp UDDI Bạn sẽ cần một tài khoản hộ chiếu Microsoft để tiếp tục. Nếu bạn có một tài khoản như vậy, nhập vào những chi tiết của bạn (xem Hình 17.14). Kích nút Continue để tiếp tục.

Page 122: Lap trinhcosodulieuvoi c-sharp_phan-3

Hình 17.14: đăng nhập sử dụng một tài khoản hộ chiếu Microsoft Ghi nhớ: nếu bạn không có một tài khoản hộ chiếu, kích liên kết "Get One Now" và đăng ký cho một tài khoản hộ chiếu. Nhập vào địa chỉ email của bạn, tên và số điện thoại trong trang UDDI Business Registry Node (xem Hình 17.15). Tên và số điện thoại ở gần đáy của trang và bạn sẽ cần phải cuộn xuống để xem chúng. Kích nút Save để tiếp tục.

Hình 17.15: Nhập vào địa chỉ email , tên và số điện thoại của bạn Đọc những điều khoản sử dụng của trang và kích Accept (sự chấp nhận) nếu bạn muốn tiếp tục.

Page 123: Lap trinhcosodulieuvoi c-sharp_phan-3

Hình 17.16: những điều khỏan sử dụng của trang Nhập vào tên Doanh nghiệp của bạn và một mô tả tùy chọn (xem Hình 17.17). Kích Save để tiếp tục.

Hình 17.17: Thiết đặt tên giao dịch và sự mô tả Bạn sẽ được yêu cầu chọn môi trường UDDI lần nữa, vì vậy phải bảo đảm rằng nút rađiô UDDI Test Environment đã được chọn kiểm, và kích Submit để tiếp tục.

Page 124: Lap trinhcosodulieuvoi c-sharp_phan-3

Chắc chắn rằng tổ chức (organization) của bạn được chọn, và kích Submit để tiếp tục. Tiếp theo, nhập vào những chi tiết cho dịch vụ mạng của bạn. Nhập vào một tên cho dịch vụ mạng của bạn, cùng với một sự mô tả. URL .asmx cho NorthwindWebService của bạn sẽ tương tự như URL sau :

http://localhost/NorthwindWebService/Customers.asmx .Wsdl URL của bạn sẽ tương tự như URL sau :

http://localhost/NorthwindWebService/Customers.asmx?WSDL

Chọn những đặc tính cho loại dịch vụ của bạn. Những thiết đặt này được trình bày trong Hình 17.18. Kích Submit (đệ trình) để đăng ký dịch vụ mạng của bạn.

Hình 17.18: Thiết đặt những chi tiết dịch vụ mạng Như thế đó. Bạn đã đăng ký một cách thành công dịch vụ mạng của bạn. Cứ thoải mái tìm kiếm và khảo sát những dịch vụ mạng hiện thời dã đăng ký sử dụng trang Find A Service. Tóm lược Một dịch vụ mạng là một thành phần phần mềm mà bạn có thể điểm qua Mạng, và một trong số những đặc tính khóa của .NET là khả năng dễ dàng tạo ra dịch vụ Mạng. Những công ty có thể tạo ra những dịch vụ Mạng để cho phép những khách hàng của họ tương tác với họ. Vì những dịch vụ Mạng trả về và chấp nhận dữ liệu trong form của những tài liệu XML, những dịch vụ Mạng thực sự là nền tảng độc lập. Chẳng hạn, bạn có thể có một dịch vụ mạng viềt bởi C# giao tiếp với dịch vụ Mạng khác viết bằng ngôn ngữ Java, thông qua dữ liệu trong form của những tài liệu XML. Trong chương này, bạn đã thấy cách tạo ra một dịch vụ Mạng sử dụng VS .NET và sử dụng nó trong một ứng dụng Windows như thế nào. Bạn cũng thấy cách đăng ký một dịch vụ Mạng như thế nào để những tổ chức khác có thể sử dụng dịch vụ của bạn. Tôi hy vọng bạn tìm thấy trong sách này nhiều thông tin hữu ích, và tôi hy vọng có được sự quan tâm của bạn! Lập trình Cơ sở dữ liệu với C# là một chủ đề rất lớn , Nhưng được vũ trang với sách này, Tôi tin tưởng bạn sẽ làm chủ được nó.