Tập bài giảng Lập trình trên nền web (Phần 2)

pdf 87 trang Gia Huy 17/05/2022 3500
Bạn đang xem 20 trang mẫu của tài liệu "Tập bài giảng Lập trình trên nền web (Phần 2)", để tải tài liệu gốc về máy bạn click vào nút DOWNLOAD ở trên

Tài liệu đính kèm:

  • pdftap_bai_giang_lap_trinh_tren_nen_web_phan_2.pdf

Nội dung text: Tập bài giảng Lập trình trên nền web (Phần 2)

  1. CHƢƠNG 4: TRUY NHẬP CƠ SỞ DỮ LIỆU 4.1. Giới thiệu chung Khi phát triển các ứng dụng trên nền Web thì công việc chủ yếu phải giải quyết là xử lý các nghiệp vụ, trong đó phần lớn là xử lý cơ sở dữ liệu. Trong môi trƣờng phát triển Microsoft .NET tất cả các ứng dụng Web Form hay Win Form đều thống nhất sử dụng chung một bộ thƣ viện để truy xuất và thao tác cơ sở dữ liệu gọi là ADO.NET (Active Data Object). ADO.NET là một tập các lớp nằm trong bộ thƣ viện lớp cơ sở của .NET Framework, cho phép các ứng dụng Windows (nhƣ C#, VB.NET) hay ứng dụng Web (nhƣ ASP.NET) thao tác dễ dàng với các nguồn dữ liệu. Mục tiêu chính của ADO.NET là: - Cung cấp các lớp để thao tác cơ sử dữ liệu trong cả hai môi trƣờng là phi kết nối (Disconected data) và kết nối (Connected data). - Tích hợp chặt chẽ với XML (Extensible Markup Language). - Tƣơng tác với nhiều nguồn dữ liệu thông qua mô tả dữ liệu chung. - Tối ƣu truy cập nguồn dữ liệu (OLE DB & SQL Server). - Làm việc trên môi trƣờng Internet. ADO.NET bao gồm hai Provider (hai bộ thƣ viện) để thao tác với các cơ sở dữ liệu là: OLE DB Provider (nằm trong System.Data.OLEDB) dùng để truy xuất đến cơ sở dữ liệu nào có hỗ trợ OLEDB; SQL Provider (nằm trong System.Data.SQLClient) chuyên dùng để truy xuất đến cơ sở dữ liệu SQL Server (không qua OLE DB nên nhanh hơn). Hiện nay, các hãng thứ ba cung cấp các Provider khác nhƣ : MySQL, Oracle provider cho phép ứng dụng .NET truy xuất đến cơ sở dữ liệu không phải của Microsoft. Hình 4.1. Vị trí của ADO.NET trong kiến trúc của .net Framework
  2. Từ kiến trúc ta thấy rằng: ADO.NET là một thành phần nội tại (Instrict) của .NET Framework. Do vậy nó có thể đƣợc sử dụng trong tất cả các ngôn ngữ hỗ trợ .NET nhƣ C#, VB.NET mà không có sự khác biệt. 4.2. Kiến trúc của ADO.NET ADO.NET là một phần của .NET Framework, đƣợc xem là “bộ thƣ viện lớp” chịu trách nhiệm xử lý dữ liệu trong ngôn ngữ MS .NET. ADO.NET gồm hai thành phần chính cho việc truy xuất và điều khiển dữ liệu đó là các trình cung cấp dữ liệu .NET Framework (.NET Framework Data Provider) và DataSet. Mô hình dƣới đây minh họa mối quan hệ giữa trình cung cấp dữ liệu của .NET Framework và DataSet. Hình 4.2. Kiến trúc ADO.NET Việc kết nối giữa ứng dụng và cở sở dữ liệu thông qua ADO.NET theo chế độ Connected và Disconnected . Connected: Cơ chế này yêu cầu phải thực hiện kết nối với Database trong khi đang thực hiện các thao tác với dữ liệu. Các đối tƣợng của cơ chế này là: + Connection: Đối tƣợng quản lý đóng/mở kết nối tới Database. + Command: Đối tƣợng thực hiện các câu lệnh tƣơng tác truy vấn, rút trích dữ liệu từ database sau khi đã thiết lập kết nối tới dữ liệu và trả về kết quả. + DataReader: Đối tƣợng xử lý đọc dữ liệu từ cơ sở dữ liệu. + DataAdapter: Đây là đối tƣợng rất quan trọng của ADO.NET là cầu nối của Database và Dataset (Dataset là đối tƣợng ngắt kết nối), vì đối tƣợng “ngắt kết nối” Dataset không thể tƣơng tác trực tiếp với Database nên cần một đối tƣợng trung gian lấy
  3. dữ liệu từ Database đó chính là DataAdapter. DataAdpater khi thao tác với Database vẫn phải duy trì kết nối nên nó đƣợc liệt kê vào dạng “kết nối” nhƣng bản chất phục vụ cho việc “ngắt kết nối”. Disconnected: Chỉ có một đối tƣợng chịu trách nhiệm ngắt kết nối đó chính là DataSet. Nhiệm vụ của DataSet là nhận dữ liệu về từ DataAdapter và xử lý nó. DataSet có thể đƣợc xem nhƣ một Database trong bộ nhớ gồm tất cả các bảng, quan hệ DataSet có nhiều đối tƣợng đƣợc xem là “con” nhƣ: DataTable, cấp thấp hơn của DataTable có các đối tƣợng DataRow, DataColumn, DataRelation. Ngoài ra còn có các đối tƣợng nhóm nhƣ DataTableCollection, DataRowCollection, DataColumnCollection. Việc sử dụng DataSet là một tiến bộ lớn của kiến trúc ADO.NET. Hình 4.3. Cơ chế kết nối ADO.NET 4.3. Tìm hiểu trình cung cấp dữ liệu của ADO.NET ADO.NET hỗ trợ nhiều trình cung cấp dữ liệu, mỗi trình cung cấp tƣơng tác với một hệ quản trị cơ sở dữ liệu (DBMS) cụ thể. Lợi ích đầu tiên của phƣơng pháp này là một trình cung cấp dữ liệu cụ thể có thể đƣợc lập trình để truy xuất đến bất cứ thuộc tính nào của một DBMS mà đƣợc chỉ định bởi trình cung cấp đó. Lợi ích khác đó là trình cung cấp dữ liệu có thể kết nối ngay lập tức đến cơ sử dữ liệu mà không thông qua tầng ánh xạ trung gian giữa các lớp.
  4. Hình 4.4. Các lớp giữa code và nguồn dữ liệu Một trình cung cấp dữ liệu là tập hợp các kiểu đƣợc định nghĩa trong namespace System.Data, cho biết cách để giao tiếp với một nguồn dữ liệu cụ thể. Một trình cung cấp định nghĩa một tập hợp các kiểu lớp mà cung cấp các chức năng cơ bản. Các đối tƣợng cơ bản của một trình cung cấp dữ liệu ADO.NET. Đối tƣợng Lớp cơ sở Giao diện Ý nghĩa Connection DbConnection IDbConnection Cung cấp khả năng kết nối và ngắt kết nối với nguồn dữ liệu. Command DbCommand IDbCommand Trình bày một truy vấn SQL hoặc stored procedure. DataReader DbDataReader IDataReader Đọc nguồn dữ liệu theo một IDataRecord chiều. DataAdapter DbDataAdapter IDataAdapter Chuyển DataSets giữa các đối IDbDataAdapter tƣợng gọi (caller) và kho dữ liệu. Parameter DbParameter IDataParameter Miêu tả tên gọi tham số bên IDbDataParameter trong truy vấn có tham số (parameterized query). Transaction DbTransaction IDbTransaction Đóng gói (Encapsulates) một database transaction.
  5. Mặc dù tên của các đối tƣợng này sẽ khác nhau tùy thuộc trình cung cấp dữ liệu (ví dụ: SqlConnection khác với OracleConnection khác với OdbcConnection khác với MySqlConnection) nhƣng mỗi đối tƣợng đều kế thừa từ một lớp cơ sở (base class) (DbConnection trong trƣờng hợp các đối tƣợng kết nối) và thi hành interface (nhƣ IDbConnection). Các trình cung cấp dữ liệu ADO.NET đƣợc cung cấp bởi Microsoft. Data Provider Namespace Assembly OLE DB System.Data.OleDb System.Data.dll Microsoft SQL Server System.Data.SqlClient System.Data.dll Microsoft SQL Server System.Data.SqlServerCe System.Data.SqlServerCe.dll Mobile ODBC System.Data.Odbc System.Data.dll Oracle System.Data.OracleClient System.Data.OracleClient.dll Trình cung cấp dữ liệu OLE DB và ODBC chỉ hữu ích nếu tƣơng tác với một DBMS mà không định nghĩa một trình cung cấp dữ liệu .NET cụ thể. 4.4. Các namespace của ADO.NET .NET cung cấp một số namespace cho ADO.NET, một vài namespace trong đó đƣợc thể hiện trong bảng sau: Namespace Ý nghĩa Microsoft.SqlServer.Server Namespace này cung cấp các loại phục vụ việc tích hợp CLR và SQL Server 2005 đƣợc dễ dàng. System.Data Namespace này định nghĩa các loại ADO.NET cơ sở đƣợc sử dụng bởi tất cả trình cung cấp dữ liệu, bao gồm các Interface phổ biến và các loại thể hiện lớp ngắt kết nối. (DataSet, DataTable, etc.). System.Data.Common Namespace này chứa các loại đƣợc dùng chung trong tất cả các trình cung cấp của ADO.NET, bao gồm các lớp cơ sở ảo (abstract base classe) phổ biến. System.Data.Sql Namespace này chứa các loại mà cho phép nhận ra các thể hiện Microsoft SQL Server đƣợc cài đặt trên mạng cục bộ hiện hành. System.Data.SqlTypes Namespace này chứa các loại dữ liệu tự nhiên (native data types) đƣợc dùng bởi Microsoft SQL Server.
  6. Namespace System.Data: Namespace này chứa các loại đƣợc dùng chung trong tất cả các trình cung cấp dữ liệu của ADO.NET. Các thành viên chính của System.Data Namespace. Namespace Ý nghĩa Constraint Trình bày (Represent) một ràng buộc cho một đối tƣợng DataColumn đã cho. DataColumn Trình bày một column bên trong một đối tƣợng DataTable. DataRelation Trình bày mối quan hệ parent/child giữa hai đối tƣợng DataTable. DataRow Trình bày một dòng bên trong một đối tƣợng DataTable. DataSet Trình bày một vùng trong bộ nhớ của dữ liệu bao gồm mọi thành phần của đối tƣợng DataTable có quan hệ với nhau. DataTable Trình bày bảng trong bộ nhớ DataTableReader Cho phép xem xét một DataTable. DataView Trình bày một view của một DataTable cho việc sắp xếp, việc lọc, việc tìm kiếm, chỉnh sửa và điều hƣớng. IDataAdapter Định nghĩa cách hành xử chính (core behavior) của một đối tƣợng DataAdapter. IDataParameter Định nghĩa cách hành xử chính (core behavior) của một đối tƣợng parameter. IDataReader Định nghĩa cách hành xử chính (core behavior) của một đối tƣợng DataReader. IDbCommand Định nghĩa cách hành xử chính (core behavior) của một đối tƣợng command. IDbDataAdapter Kế thừa IDataAdapter để cung cấp thêm các chức năng của một đối tƣợng DataAdapter IDbTransaction Định nghĩa cách hành xử cốt lõi (core behavior) của một đối tƣợng Transaction. IDbConnection Interface: Đƣợc thi hành bởi đối tƣợng connection của trình cung cấp dữ liệu. Interface này định nghĩa một tập hợp các thành phần đƣợc dùng để tạo một kết nối đến kho dữ liệu và nó cũng cho phép lấy đƣợc đối tƣợng Transaction của trình cung cấp dữ liệu. Dƣới đây định nghĩa của IDbConnection.
  7. public interface IDbConnection : IDisposable { string ConnectionString { get; set; } int ConnectionTimeout { get; } string Database { get; } ConnectionState State { get; } IDbTransaction BeginTransaction(); IDbTransaction BeginTransaction(IsolationLevel il); void ChangeDatabase(string databaseName); void Close(); IDbCommand CreateCommand(); void Open(); } Phƣơng thức Close() là tƣơng đƣơng về mặt chức năng với việc gọi phƣơng thức Dispose() trực tiếp hoặc gián tiếp bên trong phạm vi using của C#. IDbTransaction Interface: Việc nạp chồng phƣơng thức BeginTransaction() (overloaded BeginTransaction() method) đƣợc định nghĩa bởi IDbConnection cung cấp truy xuất đến đối tƣợng Transaction của trình cung cấp. Việc sử dụng các thành phần đƣợc định nghĩa bởi IDbTransaction, có thể tƣơng tác với một phiên chuyển giao (transactionnal session) và kho dữ liệu ở dƣới. public interface IDbTransaction : IDisposable { IDbConnection Connection { get; } IsolationLevel IsolationLevel { get; } void Commit(); void Rollback(); } IDbCommand Interface: IDbCommand Interface đƣợc thi hành bởi đối tƣợng command của trình cung cấp dữ liệu. Đối tƣợng command cho phép thao tác với các câu lệnh SQL, Stored Procedures và các truy vấn có tham số (parameterized queries). Trong phần bổ sung, các đối tƣợng command truy xuất đến DataReader của trình cung cấp dữ liệu thông qua việc nạp chồng phƣơng thức ExecuteReader() (overloaded ExecuteReader() method). public interface IDbCommand : IDisposable { string CommandText { get; set; }
  8. int CommandTimeout { get; set; } CommandType CommandType { get; set; } IDbConnection Connection { get; set; } IDataParameterCollection Parameters { get; } IDbTransaction Transaction { get; set; } UpdateRowSource UpdatedRowSource { get; set; } void Cancel(); IDbDataParameter CreateParameter(); int ExecuteNonQuery(); IDataReader ExecuteReader(); IDataReader ExecuteReader(CommandBehavior behavior); object ExecuteScalar(); void Prepare(); } Interface IDbDataParameter và IDataParameter: Interface này cung cấp truy xuất đến một tập hợp các loại lớp tùy ý (compliant) IDbDataParameter (ví dụ: các đối tƣợng tham số): public interface IDbDataParameter : IDataParameter { byte Precision { get; set; } byte Scale { get; set; } int Size { get; set; } } IDbDataParameter kế thừa (extend) interface IDataParameter để có đƣợc các hành xử (behaveors) bổ sung sau đây: public interface IDataParameter { DbType DbType { get; set; } ParameterDirection Direction { get; set; } bool IsNullable { get; } string ParameterName { get; set; } string SourceColumn { get; set; } DataRowVersion SourceVersion { get; set; } object Value { get; set; } }
  9. Chức năng của các Interface IDbDataParameter và IDataParameter cho phép trình bày các tham số bên trong một lệnh SQL (bao gồm Stored Procedures) qua các đối tƣợng parameter của ADO.NET cụ thể hơn là những kí tự chuỗi hard-coded. IDbDataAdapter and IDataAdapter Interfaces: IDbDataAdapter Interface định nghĩa một tập hợp các thuộc tính mà đƣợc dùng để duy trì các câu lệnh SQL cho các hoạt động có liên quan đến select, insert, update và delete. public interface IDbDataAdapter : IDataAdapter { IDbCommand DeleteCommand { get; set; } IDbCommand InsertCommand { get; set; } IDbCommand SelectCommand { get; set; } IDbCommand UpdateCommand { get; set; } } Có bốn thuộc tính đƣợc thêm vào DataAdapter cũng đƣợc định nghĩa trong Interface cơ sở, IDataAdapter. Interface này định nghĩa chức năng chính của một loại DataAdapter: khả năng chuyển các DataSet giữa đối tƣợng gọi và kho dữ liệu bên dƣới sử dụng các phƣơng thức Fill() và Update(). IDataAdapter Interface cho phép ánh xạ các tên cột trong bảng dữ liệu thành các tên hiển thị thân thiện với ngƣời dùng hơn thông qua thuộc tính TableMappings. public interface IDataAdapter { MissingMappingAction MissingMappingAction { get; set; } MissingSchemaAction MissingSchemaAction { get; set; } ITableMappingCollection TableMappings { get; } int Fill(System.Data.DataSet dataSet); DataTable[] FillSchema(DataSet dataSet, SchemaType schemaType); IDataParameter[] GetFillParameters(); int Update(DataSet dataSet); } IDataReader and IdataRecord: Interface IDataReader trình bày các hành sử (behaviors) phổ biến đƣợc hỗ trợ bởi một đối tƣợng DataReader cho trƣớc. public interface IDataReader : IDisposable, IDataRecord { int Depth { get; } bool IsClosed { get; } int RecordsAffected { get; }
  10. void Close(); DataTable GetSchemaTable(); bool NextResult(); bool Read(); } IDataReader kế thừa IDataRecord, định nghĩa một số thành phần cho phép trích một giá trị đƣợc phân loại một cách rõ ràng. Dƣới đây là danh sách không đầy đủ của các phƣơng thức GetXXX() khác nhau đƣợc định nghĩa bởi IDataRecord. public interface IDataRecord { int FieldCount { get; } object this[ string name ] { get; } object this[ int i ] { get; } bool GetBoolean(int i); byte GetByte(int i); char GetChar(int i); DateTime GetDateTime(int i); Decimal GetDecimal(int i); float GetFloat(int i); short GetInt16(int i); int GetInt32(int i); long GetInt64(int i); bool IsDBNull(int i); } Phƣơng thức IDataReader.IsDBNull() thiết lập giá trị cho một trƣờng là null. 4.5. Các lớp thao tác với cơ sở dữ liệu 4.5.1. Lớp Connection Để kết nối với cơ sở dữ liệu và đọc các mẫu tin sử dụng đối tƣợng DataReader, thực hiện các bƣớc sau: - Chỉ định, cấu hình và mở đối tƣợng kết nối. - Chỉ định và cấu hình đối tƣợng Command, chỉ rõ đối tƣợng Connection nhƣ một Constructor có đối số hoặc qua thuộc tính Connection. - Gọi ExecuteReader() trên đối tƣợng Command đã đƣợc cấu hình. - Xử lý mỗi mẫu tin sử dụng phƣơng thức Read() của DataReader.
  11. Hình 4.5. Kết nối đến cơ sở dữ liệu và đọc dữ liệu Connection là đối tƣợng có nhiệm vụ thực hiện kết nối đến cơ sở dữ liệu để các đối tƣợng nhƣ Command thao tác với cơ sở dữ liệu thông qua Connection này. Các dạng khai báo chuỗi kết nối tuỳ theo loại Database Provider. [OleDB Provider] OleDbConnection myConnection = new OleDbConnection(); // Windows Authentication myConnection.ConnectionString = "Provider=SQLOLEDB.1; Data Source = localhost; " +"Initial Catalog=Pubs;Integrated Security=SSPI"; // SQL Authentication myConnection.ConnectionString = "Provider=SQLOLEDB.1; Data Source = localhost;" + "Initial Catalog=Pubs;User ID=sa;Password=123456"; [SQLServer Provider] SqlConnection myConnection = new SqlConnection(); myConnection.ConnectionString = "Data Source=localhost;" + "Initial Catalog = Pubs;Integrated Security=SSPI"; [AttachDBFile] (tập tin cơ sở dữ liệu) myConnection.ConnectionString = @"Data Source=localhost\SQLEXPRESS;" + @"AttachDBFilename=|DataDirectory|\Pubs.mdf;Integrated Security=True"; Khi làm việc với một trình cung cấp dữ liệu là thiết lập một session với nguồn dữ liệu sử dụng đối tƣợng connection (kế thừa từ DbConnection). Các đối tƣợng Connection của .NET đƣợc cung cấp với một chuỗi kết nối đƣợc định dạng, gồm một số cặp name/value đƣợc phân cách bởi dấu chấm phẩy (;). Thông tin này đƣợc dùng để chỉ định tên máy sẽ kết nối, các thiết lập bảo mật đƣợc yêu cầu, tên của cơ sở dữ liệu trên máy đó và thông tin trình cung cấp dữ liệu cụ thể khác.
  12. Tên Initial Catalog xác định tên cơ sở dữ liệu. Data Source xác định tên máy chứa cơ sở dữ liệu. Ở đây, (local) cho phép định nghĩa một Token riêng biệt (single) để chỉ rõ máy cục bộ hiện hành, khi token \SQLEXPRESS cho trình cung cấp dữ liệu SQL biết đang kết nối đến bản cài đặt SQL Server Express edition (nếu đã có Pubs trên SQL Server 2005/2008 hoặc các phiên bản trƣớc đây chỉ rõ Data Source=(local)\SQLEXPRESS). Integrated Security thiết lập thông tin bảo mật, nếu chọn Integrated Security là SSPI (tƣơng đƣơng true), để sử dụng tài khoản Windows hiện hành để xác nhận quyền ngƣời dùng. User ID và Password thiết lập thông tin bảo mật, nếu chọn để sử dụng tài khoản SQL Server hiện hành để xác nhận quyền ngƣời dùng. Sau khi chuỗi kết nối đƣợc thiết lập, gọi Open() mở kết nối với cơ sở dữ liệu. Ngoài việc bổ sung các thành phần ConnectionString, Open() và Close() một đối tƣợng kết nối cung cấp một số thành phần mà cho phép thêm vào các thiết lập thuộc về cấu hình kết nối nhƣ là các thiết lập Timeout thông tin thuộc về giao tác (transactional). Các thành phần của DbConnection. Thành phần Ý nghĩa BeginTransaction() Phƣơng thức này đƣợc sử dụng để bắt đầu một database Transaction. ChangeDatabase() Phƣơng thức này thay đổi cơ sở dữ liệu trên một kết nối mở (open connection) Close() Phƣơng thức này dùng để đóng kết nối ConnectionString Thuộc tính này chứa các thông tin để kết nối. ConnectionTimeout Thuộc tính này trả ra một khoảng thời gian chờ trong khi thiết lập một kết nối trƣớc khi kết thúc và tạo ra một lỗi (mặc định là 15 giây). Database Thuộc tính này lấy ra tên của cơ sở dữ liệu đƣợc duy trì bởi đối tƣợng connection. DataSource Thuộc tính này lấy vị trí của cơ sở dữ liệu đƣợc duy trì bởi đối tƣợng connection. GetSchema() Phƣơng thức này trả ra một DataSet mà chứa thông tin bảng từ nguồn dữ liệu. Open() Phƣơng thức này dùng để mở kết nối State Thuộc tính này thiết lập trạng thái hiện hành của việc kết nối, đƣợc thể hiện bởi việc liệt kê ConnectionState.
  13. Ví dụ: Thực hiện việc tạo kết nối đến cơ sở dữ liệu Pubs trong MS SQL Server sử dụng đối tƣợng SqlConnection với chuỗi kết nối có dạng sau: Xác thực với Windows Authenticate string connectionString = "Data Source=localhost\\SQLEXPRESS;Initial Catalog=Pubs; Integrated Security=SSPI"; Xác thực với SQL Authenticate string connectionString = "Data Source=localhost\\SQLEXPRESS;Initial Catalog=Pubs; User ID=sa;Password=123456"; string connectionString = “Server=localhost; Database= Pubs; Uid=sa; Pwd=123456”; Tạo đối tƣợng Connection SqlConnection myConnection = new SqlConnection(connectionString); Mở kết nối đến cơ sở dữ liệu myConnection.Open(); Đóng kết nối đến cơ sở dữ liệu myConnection.Close(); Nội dung thiết kế trang ConnectionTester.aspx Nội dung trang ConnectionTester.aspx.cs public partial class ConnectionTester : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { } protected void cmdConnect_Click(object sender, EventArgs e)
  14. { string connectionString = "Data Source=localhost\\SQLEXPRESS; Initial Catalog=Pubs;"; if (optWindows.Checked) { connectionString += "Integrated Security=SSPI"; } else { connectionString += "User ID=sa;Password=123456"; } SqlConnection myConnection = new SqlConnection(connectionString); try { myConnection.Open(); lblInfo.Text = " Server Version: " + myConnection.ServerVersion; lblInfo.Text += " Connection Is: " + myConnection.State.ToString(); } catch (Exception err) { lblInfo.Text = "Error reading the database. "; lblInfo.Text += err.Message; } finally { myConnection.Close(); lblInfo.Text += " Now Connection Is: "; lblInfo.Text += myConnection.State.ToString(); } Hình 4.6 Kết quả thực thi trƣờng hợp kết nối cơ sở dữ liệu bị lỗi và thành công Một cách khác, thực hiện việc khai báo cấu hình ConnectionString trong Web.config : không cần phải hard-code ở các trang mã lệnh.
  15. Lấy nội dung ConnectionString trong thẻ trong tập tin Web.config phải khai báo thêm : using System.Web.Configuration; private string connectionString= WebConfigurationManager.ConnectionStrings["Pubs"]. ConnectionString; 4.5.2. Lớp Command Sau khi kết nối với cơ sở dữ liệu, sau đó submit các truy vấn SQL đến cơ sở dữ liệu. Kiểu SqlCommand (kế thừa từ DbCommand). Kiểu của Command theo lý thuyết sử dụng thuộc tính CommandType, có thể lấy ra bất cứ giá trị nào từ CommandType enum: public enum CommandType { StoredProcedure, TableDirect, Text // Default value. } Khi tạo một đối tƣợng Command cũng có thể kết hợp truy vấn SQL nhƣ một Constructor có tham số hoặc trực tiếp thông qua thuộc tính CommandText. Ngoài ra khi đang tạo một đối tƣợng command, cần chỉ rõ kết nối đƣợc sử dụng. Mặt khác, có thể tạo một Constructor có đối số hoặc thông qua thuộc tính Connection. Ví dụ SqlConnection cn = new SqlConnection(); string strSQL = "Select * From Customers"; SqlCommand myCommand = new SqlCommand(strSQL, cn); SqlCommand testCommand = new SqlCommand(); testCommand.Connection = cn; testCommand.CommandText = strSQL; Các thành phần của DbCommand Thành phần Ý nghĩa CommandTimeout Lấy ra hoặc thiết lập thời gian chờ trong khi đang thực thi lệnh trƣớc khi kết thúc. Connection Lấy ra hoặc thiết lập DbConnection đƣợc dùng bởi thể hiện này của DbCommand.
  16. Parameters Lấy ra tập hợp các kiểu của DbParameter đƣợc dùng cho một truy vấn có tham số. Cancel() Hủy bỏ việc thực thi của một lệnh. ExecuteReader() Thực hiện câu lệnh trong CommandText. Kết quả trả về là SqlDataReader của trình cung cấp dữ liệu. ExecuteNonQuery() Thực hiện câu lệnh trong CommandText và không có kết quả trả về. ExecuteScalar() Thực hiện câu lệnh trong CommandText, kết quả trả về là một giá trị đơn. ExecuteXmlReader() Phƣơng thức này trả ra một System.Xml.XmlReader mà cho phép xử lý luồng đầu vào của XML Prepare() Tạo một phiên bản đƣợc chuẩn bị (hoặc đƣợc biên dịch) của lệnh trên nguồn dữ liệu. Ví dụ: Tính tổng số bản ghi của bảng Orders trong cơ sở dữ liệu nwind.mdb SqlConnection cnn = new SqlConnection(); SqlCommand cmd = new SqlCommand(); cnn.ConnectionString = “Server=localhost; database=Northwind; user id=sa; password=sa”; cmd.Connection = cnn; cmd.CommandText = “SELECT COUNT(*) FROM Orders”; cmd.CommandType = CommandType.Text; cnn.Open(); int count = (int)cmd.ExecuteScalar(); cnn.Close(); Ví dụ: Thêm một bản ghi vào bảng dtb trong cơ sở dữ liệu QLHS SqlConnection cnn = new SqlConnection(); SqlCommand cmd = new SqlCommand(); cnn.ConnectionString = “Server=localhost; database=QLHS; user id=sa; password=sa”; cmd.Connection = cnn; cmd.CommandText =“INSERT INTO HocSinh(id_hocsinh, tenhocsinh, dtb)” + “VALUES(5, „Nguyễn Văn A‟, 8.5)”; cmd.CommandType = CommandType.Text; cnn.Open(); cmd.ExecuteNonQuery(); cnn.Close();
  17. Đối tƣợng Command và các truy vấn có tham số. Các truy vấn có tham số thực thi nhanh hơn một chuỗi SQL bình thƣờng, vì chúng đƣợc phân tách một cách rõ ràng (chuỗi SQL đƣợc gắn đến thuộc tính CommandText). Để hỗ trợ các truy vấn có tham số đối tƣợng Command của ADO.NET duy trì một tập hợp của các đối tƣợng tham số riêng biệt. Mặc định, tập hợp này empty, nhƣng dễ dàng để thêm bất cứ giá trị nào của đối tƣợng tham số mà ánh xạ đến một “tham số thay thế” trong truy vấn SQL. Khi muốn kết hợp một tham số bên trong một truy vấn SQL đến một thành viên trong tập hợp các tham số của đối tƣợng command, thêm tiền tố @ trƣớc tham số SQL. Để xây dựng một truy vấn có tham số, chúng ra bắt đầu với DbParameter (là lớp cở sở cho đối tƣợng tham số cụ thể của một trình cung cấp). Lớp này chứa một số thuộc tính mà cho phép cấu hình tên, kích cỡ và kiểu dữ liệu của tham số, cũng nhƣ các đặc điểm khác nhƣ là hƣớng của tham số. Các thành phần chính của DbParameter Thuộc tính Ý nghĩa DbType Lấy ra hoặc thiết lập kiểu dữ liệu tự nhiên từ nguồn dữ liệu, đƣợc trình bày nhƣ kiểu dữ liệu CLR. Direction Lấy ra hoặc thiết lập tham số chỉ nhập, chỉ xuất, cả hai, hoặc trả ra tham số giá trị. IsNullable Lấy ra hoặc thiết lập tham số chấp nhận các gía trị Null. ParameterName Lấy ra hoặc thiết lập tên của DbParameter. Size Lấy ra hoặc thiết lập kích cỡ tham số tối thiểu của dữ liệu (chỉ hữu ích cho dữ liệu là văn bản). Value Lấy ra hoặc thiết lập giá trị cho tham số. Minh họa tập hợp của các đối tƣợng Command của các đối tƣợng DBParameter quan sát đoạn code sau : string insertSQL; insertSQL = "INSERT INTO Authors ("; insertSQL += "au_id, au_fname, au_lname, "; insertSQL += "phone, address, city, state, zip, contract) "; insertSQL += "VALUES ("; insertSQL += "@au_id, @au_fname, @au_lname, "; insertSQL += "@phone, @address, @city, @state, @zip, @contract)"; SqlConnection con = new SqlConnection(connectionString); SqlCommand cmd = new SqlCommand(insertSQL, con);
  18. Đƣa các Parameters với các giá trị lấy từ các điều khiển nhập vào trong đối tƣợng Command hiện tại cmd cmd.Parameters.AddWithValue("@au_id", txtID.Text); cmd.Parameters.AddWithValue("@au_fname", txtFirstName.Text); cmd.Parameters.AddWithValue("@au_Lname", txtLastName.Text); cmd.Parameters.AddWithValue("@phone", txtPhone.Text); cmd.Parameters.AddWithValue("@address", txtAddress.Text); cmd.Parameters.AddWithValue("@city", txtCity.Text); cmd.Parameters.AddWithValue("@state", txtState.Text); cmd.Parameters.AddWithValue("@zip", txtZip.Text); cmd.Parameters.AddWithValue("@contract", Convert.ToInt16(chkContract.Checked)); Hoặc khởi tạo đối tƣợng SqlParameter và đặt vào trong phần danh sách tham số của đối tƣợng cmd.Parameters.Add(new SqlParameter("@au_id", txtID.Text)); cmd.Parameters.Add(new SqlParameter("@au_fname", txtFirstName.Text)); cmd.Parameters.Add(new SqlParameter("@au_Lname", txtLastName.Text)); cmd.Parameters.Add(new SqlParameter("@phone", txtPhone.Text)); cmd.Parameters.Add(new SqlParameter("@address", txtAddress.Text)); cmd.Parameters.Add(new SqlParameter("@city", txtCity.Text)); cmd.Parameters.Add(new SqlParameter("@state", txtState.Text)); cmd.Parameters.Add(new SqlParameter("@zip", txtZip.Text)); cmd.Parameters.Add(new SqlParameter("@contract",Convert.ToInt16(chkContract.Checked))); Ví dụ: Tạo trang AuthorManager.aspx thiết vế với giao diện sau : Hình 4.7. Giao diện trang AuthorManager.aspx
  19. Trang AuthorManager.aspx.cs public partial class AuthorManager : System.Web.UI.Page { private string connectionString = WebConfigurationManager.ConnectionStrings["Pubs"].ConnectionString; protected void Page_Load(object sender, EventArgs e) { if (!this.IsPostBack) { FillAuthorList(); } } private void FillAuthorList() { lstAuthor.Items.Clear(); string selectSQL = "SELECT au_lname, au_fname, au_id FROM Authors"; SqlConnection con = new SqlConnection(connectionString); SqlCommand cmd = new SqlCommand(selectSQL, con); SqlDataReader reader; try { con.Open(); while (reader.Read()) { ListItem newItem = new ListItem(); newItem.Text = reader["au_lname"] + ", " + reader["au_fname"]; newItem.Value = reader["au_id"].ToString(); lstAuthor.Items.Add(newItem); } reader.Close(); } catch (Exception err) { lblResults.Text = "Error reading list of names. "; lblResults.Text += err.Message; } finally {
  20. con.Close(); } } protected void lstAuthor_SelectedIndexChanged(object sender, EventArgs e) { string selectSQL; selectSQL = "SELECT * FROM Authors "; selectSQL += "WHERE au_id='" + lstAuthor.SelectedItem.Value + "'"; SqlConnection con = new SqlConnection(connectionString); SqlCommand cmd = new SqlCommand(selectSQL, con); SqlDataReader reader; try { con.Open(); reader = cmd.ExecuteReader(); reader.Read(); txtID.Text = reader["au_id"].ToString(); txtFirstName.Text = reader["au_fname"].ToString(); txtLastName.Text = reader["au_lname"].ToString(); txtPhone.Text = reader["phone"].ToString(); txtAddress.Text = reader["address"].ToString(); txtCity.Text = reader["city"].ToString(); txtState.Text = reader["state"].ToString(); txtZip.Text = reader["zip"].ToString(); chkContract.Checked = (bool)reader["contract"]; reader.Close(); lblResults.Text = ""; } catch (Exception err) { lblResults.Text = "Error getting author. "; lblResults.Text += err.Message; } finally { con.Close(); } }
  21. protected void cmdNew_Click(object sender, EventArgs e) { txtID.Text = ""; txtFirstName.Text = ""; txtLastName.Text = ""; txtPhone.Text = ""; txtAddress.Text = ""; txtCity.Text = ""; txtState.Text = ""; txtZip.Text = ""; chkContract.Checked = false; lblResults.Text = "Click Insert New to add the completed record."; } protected void cmdInsert_Click(object sender, EventArgs e) { if (txtID.Text == "" || txtFirstName.Text == "" || txtLastName.Text == "") { lblResults.Text = "Records require an ID, first name, and last name."; return; } string insertSQL; insertSQL = "INSERT INTO Authors ("; insertSQL += "au_id, au_fname, au_lname, "; insertSQL += "phone, address, city, state, zip, contract) "; insertSQL += "VALUES ("; insertSQL += "@au_id, @au_fname, @au_lname, "; insertSQL += "@phone, @address, @city, @state, @zip, @contract)"; SqlConnection con = new SqlConnection(connectionString); SqlCommand cmd = new SqlCommand(insertSQL, con); cmd.Parameters.Add(new SqlParameter("@au_id", txtID.Text)); cmd.Parameters.Add(new SqlParameter("@au_fname", txtFirstName.Text)); cmd.Parameters.Add(new SqlParameter("@au_Lname", txtLastName.Text)); cmd.Parameters.Add(new SqlParameter("@phone", txtPhone.Text)); cmd.Parameters.Add(new SqlParameter("@address", txtAddress.Text)); cmd.Parameters.Add(new SqlParameter("@city", txtCity.Text)); cmd.Parameters.Add(new SqlParameter("@state", txtState.Text)); cmd.Parameters.Add(new SqlParameter("@zip", txtZip.Text));
  22. cmd.Parameters.Add(new SqlParameter("@contract", Convert.ToInt16(chkContract.Checked))); int added = 0; try { con.Open(); added = cmd.ExecuteNonQuery(); lblResults.Text = added.ToString() + " record inserted."; } catch (Exception err) { lblResults.Text = "Error inserting record. "; lblResults.Text += err.Message; } finally { con.Close(); } if (added > 0) { FillAuthorList(); } } protected void cmdUpdate_Click(object sender, EventArgs e) { string updateSQL; updateSQL = "UPDATE Authors SET "; updateSQL += "au_fname=@au_fname, au_lname=@au_lname, "; updateSQL += "phone=@phone, address=@address, city=@city, state=@state, "; updateSQL += "zip=@zip, contract=@contract "; updateSQL += "WHERE au_id=@au_id_original"; SqlConnection con = new SqlConnection(connectionString); SqlCommand cmd = new SqlCommand(updateSQL, con); cmd.Parameters.AddWithValue("@au_fname", txtFirstName.Text); cmd.Parameters.AddWithValue("@au_Lname", txtLastName.Text); cmd.Parameters.AddWithValue("@phone", txtPhone.Text); cmd.Parameters.AddWithValue("@address", txtAddress.Text); cmd.Parameters.AddWithValue("@city", txtCity.Text);
  23. cmd.Parameters.AddWithValue("@state", txtState.Text); cmd.Parameters.AddWithValue("@zip", txtZip.Text); cmd.Parameters.AddWithValue("@contract", Convert.ToInt16(chkContract.Checked)); cmd.Parameters.AddWithValue("@au_id_original", lstAuthor.SelectedItem.Value); int updated = 0; try { con.Open(); updated = cmd.ExecuteNonQuery(); lblResults.Text = updated.ToString() + " record updated."; } catch (Exception err) { lblResults.Text = "Error updating author. "; lblResults.Text += err.Message; } finally { con.Close(); } if (updated > 0) { FillAuthorList(); } } protected void cmdDelete_Click(object sender, EventArgs e) { string deleteSQL; deleteSQL = "DELETE FROM Authors "; deleteSQL += "WHERE au_id=@au_id"; SqlConnection con = new SqlConnection(connectionString); SqlCommand cmd = new SqlCommand(deleteSQL, con); cmd.Parameters.AddWithValue("@au_id ", lstAuthor.SelectedItem.Value); int deleted = 0; try { con.Open();
  24. deleted = cmd.ExecuteNonQuery(); lblResults.Text = "Record deleted."; } catch (Exception err) { lblResults.Text = "Error deleting author. "; lblResults.Text += err.Message; } finally { con.Close(); } if (deleted > 0) { FillAuthorList(); } } } 4.5.3. Lớp DataReader Khi đã thiết lập một kết nối thực sự và câu lệnh SQL, bƣớc tiếp theo là submit truy vấn đến nguồn dữ liệu. Kiểu DbDataReader (mà thực thi giao diện IDataReader) là cách đơn giản và chắc chắn đế lấy ra thông tin từ một kho dữ liệu. Các đối tƣợng DataReader thu đƣợc từ đối tƣợng Command qua lời gọi đến ExecuteReader(). Khi làm viêc với phƣơng thức này, có thể đóng một cách tự động đối tƣợng kết nối có liên quan bới việc chỉ rõ CommandBehavior.CloseConnection. Việc sử dụng phƣơng thức Read() của DataReader để duyệt qua các mẫu tin, (trả ra giá trị false nếu duyêt qua mẫu tin cuối cùng). Chú ý rằng gọi Close() ngay khi kết thúc việc xử lý các mẫu tin để giải phóng đối tƣợng kết nối: Indexer của một đối tƣợng DataReader đã đƣợc overload để lấy một chuỗi (string) (miêu tả tên của cột) hoặc một int (miêu tả số thứ tự của cột). Do đó, có thể tránh các tên chuỗi hard-code với việc cập nhật dƣới đây (chú ý sử dụng thuộc tính FieldCount) Ví dụ: Tạo trang AuthorBrowser.aspx thực hiện đọc nội dung của bảng Authors trong cơ sở dữ liệu Pubs và đƣa vào một DropdownList. Khi chọn một giá trị trong DropdownList nội dung mẫu tin lựa chọn sẽ đƣợc hiển thị trên trang.
  25. Hình 4.8. Giao diện trang AuthorBrowser.aspx Nội dung thiết kế trang AuthorBrowser.aspx Select Author:   Nội dung trang trang AuthorBrowser.aspx.cs public partial class AuthorBrowser : System.Web.UI.Page { private string connectionString = WebConfigurationManager.ConnectionStrings["Pubs"].ConnectionString; protected void Page_Load(object sender, EventArgs e) { if (!this.IsPostBack) { FillAuthorList();
  26. } } private void FillAuthorList() { lstAuthor.Items.Clear(); string selectSQL = "SELECT au_lname, au_fname, au_id FROM Authors"; SqlConnection con = new SqlConnection(connectionString); SqlCommand cmd = new SqlCommand(selectSQL, con); SqlDataReader reader; try { con.Open(); reader = cmd.ExecuteReader(); while (reader.Read()) { ListItem newItem = new ListItem(); newItem.Text = reader["au_lname"] + ", " + reader["au_fname"]; newItem.Value = reader["au_id"].ToString(); lstAuthor.Items.Add(newItem); } reader.Close(); } catch (Exception err) { lblResults.Text = "Error reading list of names. "; lblResults.Text += err.Message; } finally { con.Close(); } } protected void lstAuthor_SelectedIndexChanged(object sender, EventArgs e) { string selectSQL; selectSQL = "SELECT * FROM Authors "; selectSQL += "WHERE au_id='" + lstAuthor.SelectedItem.Value + "'"; SqlConnection con = new SqlConnection(connectionString);
  27. SqlCommand cmd = new SqlCommand(selectSQL, con); SqlDataReader reader; try { con.Open(); reader = cmd.ExecuteReader(); reader.Read(); StringBuilder sb = new StringBuilder(); sb.Append(" "); sb.Append(reader["au_lname"]); sb.Append(", "); sb.Append(reader["au_fname"]); sb.Append(" "); sb.Append("Phone: "); sb.Append(reader["phone"]); sb.Append(" "); sb.Append("Address: "); sb.Append(reader["address"]); sb.Append(" "); sb.Append("City: "); sb.Append(reader["city"]); sb.Append(" "); sb.Append("State: "); sb.Append(reader["state"]); sb.Append(" "); lblResults.Text = sb.ToString(); reader.Close(); } catch (Exception err) { lblResults.Text = "Error getting author. "; lblResults.Text += err.Message; } finally { con.Close(); } }
  28. } Các đối tƣợng DataReader có thể thu đƣợc nhiều bộ kết quả sử dụng một đối tƣợng Command. Vid dụ, để thu đƣợc tất cả các dòng từ bảng Inventory cũng nhƣ từ bảng Customers có thể chỉ định các câu lệnh SQL select sử dụng dấu chấm phẩy (;) cuối dòng: string strSQL = "Select * From Inventory; Select * from Customers"; Khi thu đƣợc DataReader ta có thể duyệt qua các mẫu tin thông qua phƣơng thức NextResult(). do{ while (myDataReader.Read()) { for (int i = 0; i < myDataReader.FieldCount; i++) { myDataReader.GetName(i); myDataReader.GetValue(i).ToString().Trim(); } } } while (myDataReader.NextResult()); 4.5.4. Lớp DataAdapter Đóng vai trò cầu nối chuyển đổi dữ liệu giữa nguồn dữ liệu (DataSource) và các đối tƣợng thao tác dữ liệu (DataSet). Hình 4.9. Cơ chế làm việc của DataAdapter Ví dụ: SqlDataAdapter da = new SqlDataAdapter(“SELECT * FROM Orders”, “Server=localhost; database=Northwind; user id=sa; password=sa”); DataSet ds = new DataSet(); da.Fill(ds); da.Update(ds);
  29. 4.5.5. Lớp DataSet Khi sử dụng ngắt kết nối của ADO.NET sẽ thu đƣợc những đối tƣợng DataSet thƣờng trú sử dụng đối tƣợng DataAdapter của trình cung cấp dữ liệu. Chức năng của đối tƣợng DataAdapter nhƣ một cầu nối giữa tầng client và một cơ sở dữ liệu quan hệ. Đối tƣợng DataAdapter của trình cung cấp dữ liệu xử lý việc kết nối cơ sở dữ liệu một cách tự động. Khi đối tƣợng gọi nhận đƣợc đối tƣợng DataSet, tầng gọi bị ngắt kết nối từ cơ sở dữ liệu và rời khỏi với một bản sao cục bộ của dữ liệu. Đối tƣợng gọi có thể insert, delete, hoặc update những hàng từ một DataTable đã cho, nhƣng cơ sở dữ liệu vật lý không đƣợc cập nhật đến khi đối tƣợng gọi chuyển DataSet tới DataAdapter để cập nhật. DataSet là một thể hiện của dữ liệu quan hệ. Một DataSet là một lớp chứa ba colection bên trong. Hình 4.10. Mô hình của DataSet Thuộc tính Tables của DataSet cho phép truy xuất DataTableCollection chứa các DataTable riêng lẻ. Một DataSet có thể đƣợc sử dụng để thể hiện những mối quan hệ cha/con giữa các bảng của nó. Chẳng hạn, một quan hệ có thể đƣợc tạo ra giữa hai bảng để mô hình một sự ràng buộc khóa ngoại sử dụng kiểu DataRelation. Đối tƣợng này có thể sau đó đƣợc thêm vào DataRelationCollection thông qua thuộc tính Relations. Các thuộc tính chính của DataSet Thuộc tính Ý nghĩa CaseSensitive Cho biết có phải những chuỗi trong đối tƣợng DataTable là phân biệt hoa/thƣờng hay không. DataSetName Thể hiện tên một cách thân thiện của DataSet này. EnforceConstraints Đƣa ra hay thiết lập một giá trị cho biết có những quy tắc ràng buộc hay không. HasErrors Đƣa ra một giá trị cho biết có những lỗi trong bất kỳ hàng nào trong DataTables của DataSet hay không . RemotingFormat Cho phép định nghĩa cách DataSet xuất nội dung của nó ( nhị phân hay XML).
  30. DataSet cung cấp những phƣơng thức mà cho phép sao chép nội dung DataSet, điều hƣớng giữa những bảng bên trong và thiết lập những điểm bắt đầu và kết thúc của một lô những sự cập nhật. Các phƣơng thức quan trọng của DataSet Phƣơng thức Ý nghĩa AcceptChanges() Xác nhận mọi sự thay đổi gần nhất đến DataSet từ khi nó đƣợc load hay AcceptChanges(). Clear() Xóa hoàn toàn dữ liệu DataSet bằng việc loại bỏ mỗi hàng trong mỗi DataTable Clone() Sao chép cấu trúc của DataSet, bao gồm mọi DataTables, cũng nhƣ tất cả quan hệ và bất kỳ sự ràng buộc nào. Copy() Sao chép cả cấu trúc lẫn dữ liệu cho DataSet. GetChanges() Trả về một sự sao chép của DataSet chứa mọi sự thay đổi đƣợc tạo ra nó khi nó đƣợc load gần nhất hay từ khi AcceptChanges() đƣợc gọi. HasChanges() Đƣa ra một giá trị cho biết có phải DataSet có những sự thay đổi hay không. Merge() Merge DataSet này với một DataSet xác định ReadXml() Cho phép đọc dữ liệu XML vào trong DataSet. ReadXmlSchema() RejectChanges() Quay trở lại mọi sự thay đổi gần nhất đối với DataSet từ khi nó đƣợc khởi tạo hay AcceptChanges(). WriteXml() Cho phép ghi nội dung của một DataSet ra XML. WriteXmlSchema() 4.5.6. Lớp DataColumns DataColumn thể hiện một cột đơn bên trong một DataTable. DataColumn thể hiện sự thiết lập thông tin mô hình của bảng. Chẳng hạn, mô hình bảng Inventory của cơ sở dữ liệu AutoLot, sẽ tạo ra bốn DataColumns, với mỗi cột (CarID, Make, Color và PetName). Mỗi khi khởi tạo các đối tƣợng DataColumn, chúng đƣợc thêm vào trong colection Columns của kiểu DataTable (thông qua thuộc tính Column). Các thuộc tính của DataColumn: Thuộc tính Ý nghĩa AllowDBNull Thuộc tính này đƣợc dùng nếu một hàng có thể có giá trị null trong
  31. cột này. Giá trị mặc định là true. AutoIncrement Những thuộc tính này đƣợc dùng để cấu hình việc tăng tự động AutoIncrementSeed (autoincrement behavior) cho một cột nhất định. Điều Nó đƣợc AutoIncrementStep dùng khi muốn bảo đảm những giá trị là duy nhất trong một DataColumn đã. Theo mặc định, một DataColumn không hỗ trợ tăng tự động. Caption Thuộc tính này dung để thiết lập caption sẽ đƣợc hiển thị cho cột này. ColumnMapping Thuộc tính này xác định cách một DataColumn đƣợc thể hiện khi một DataSet đƣợc lƣu giữ nhƣ một tài liệu XML sử dụng phƣơng thức DataSet.WriteXml(). ColumnName Thuộc tính này thiết lập tên của cột trong colection Columns. Nếu không đặt ColumnName rõ ràng, thì giá trị mặc định là Column với hậu tố số (n +1) ( ví dụ., Column1, Column2, Column3, ). DataType Thuộc tính này định nghĩa kiểu dữ liệu (Boolean, string, float, ) đƣợc lƣu giữ trong cột. DefaultValue Thuộc tính này thiết lập giá trị mặc định đƣợc gán đến cột khi chèn những hàng mới. Expression Thuộc tính này thiết lập biểu thức đƣợc sử dụng để lọc các hàng, tính toán một giá trị của cột, hoặc tạo ra một cột kết hợp. Ordinal Thuộc tính này đƣa ra vị trí của cột trong colection Columns. ReadOnly Thuộc tính này xác định nếu chỉ đƣợc sửa đổi một lần khi đƣợc thêm vào bảng. Mặc định là false. Table Thuộc tính này đƣa ra DataTable chứa DataColumn. Unique Thuộc tính này thiết lập một giá trị cho biết có phải những giá trị trong mỗi hàng của cột là duy nhất hay không. Nếu một cột đƣợc gán một ràng buộc khóa chính, thuộc tính Unique nên đƣợc thiết lập là true. a) Xây dựng một DataColumn Tiếp tục với project SimpleDataSet cho cột CarID là khóa chính của bảng, cấu hình đối tƣợng DataColumn là read-only, duy nhất và không null (sử dụng thuộc tính ReadOnly, Unique và AllowDBNull).
  32. private void MakeTable() { DataTable table = new DataTable("Product"); DataColumn column = new DataColumn(); column.DataType = System.Type.GetType("System.Decimal"); column.AllowDBNull = false; column.Caption = "Price"; column.ColumnName = "Price"; column.DefaultValue = 25; table.Columns.Add(column); DataRow row; for(int i = 0; i < 7; i++) { row = table.NewRow(); row["Price"] = i + 1; table.Rows.Add(row); } } b) Cho phép các field tăng tự động Một khía cạnh của DataColumn có thể cấu hình tăng tự động (autoincrement). Một cột autoincrementing đƣợc sử dụng để bảo đảm rằng khi một hàng mới đƣợc thêm vào một bảng đã cho, giá trị của cột này đƣợc gán một cách tự động trên cơ sở tăng dần. Để làm việc này sử dụng những thuộc tính AutoIncrement, AutoIncrementSeed và AutoIncrementStep. Cho code sau cập nhật cấu trúc của carIDColumn DataColumn private void AddAutoIncrementColumn()*- { DataColumn column = new DataColumn(); column.DataType = System.Type.GetType("System.Int32"); column.AutoIncrement = true; column.AutoIncrementSeed = 700; column.AutoIncrementStep = 7; DataTable table = new DataTable("table"); table.Columns.Add(column); } Ở đây, đối tƣợng carIDColumn đã đƣợc cấu hình để bảo đảm rằng những dòng có giá trị tăng là 1. Vì giá trị khởi đầu đã đƣợc thiết lập là 0, nên cột này sẽ đƣợc đánh số 0, 1, 2, 3,
  33. 4.5.7. Lớp DataRow Một colection của các đối tƣợng DataColumn thể hiện mô hình của một DataTable. Còn một colection của các kiểu DataRow đại diện cho dữ liệu thực tế trong bảng. Sử dụng những thành phần của lớp DataRow có thể insert, remove và thao tác những giá trị trong bảng. Các thành phần chính của kiểu DataRow. Thành phần Ý nghĩa HasErrors Thuộc tính HasErrors trả về một giá trị Boolean cho biết nếu có GetColumnsInError() lỗi. Nhƣ vậy, phƣơng thức GetColumnsInError() đƣợc sử dụng GetColumnError() để thu đƣợc những thành phần lỗi và GetColumnError đƣợc sử ClearErrors() dụng để thu đƣợc sự mô tả lỗi, trong khi phƣơng thức RowError ClearErrors() loại bỏ lỗi cho hàng. Thuộc tính RowError cho phép cấu hình một sự mô tả lỗi cho một hàng. ItemArray Thuộc tính này thiết lập tất cả các giá trị cho hàng này sử dụng một mảng các đối tƣợng. RowState Thuộc tính này đƣợc dùng để xác định " trạng thái " hiện thời của DataRow. GetChildRows Trả về những dòng con của DataRow GetParentRows Trả về những dòng cha của DataRow Table Thuộc tính này đƣợc dùng để thu đƣợc một tham chiếu tới DataTable chứa DataRow. AcceptChanges() Những phƣơng thức này xác nhận hay loại bỏ mọi sự thay đổi RejectChanges() đến hàng từ lần cuối cùng AcceptChanges() đƣợc gọi. BeginEdit() Những phƣơng thức này bắt đầu, kết thúc, hoặc hủy bỏ một EndEdit() thao tác hiệu chỉnh trên một đối tƣợng DataRow. CancelEdit() Delete() Phƣơng thức này đánh dấu hàng sẽ đƣợc remove khi phƣơng thức AcceptChanges() đƣợc gọi. IsNull() Phƣơng thức này đƣa ra một giá trị cho biết có phải cột đƣợc xác định chứa một giá trị null hay không. 4.5.8. Lớp DataTable Kiểu DataTable định nghĩa một số lớn các thành phần, nhiều thành phần của nó giống về tên và chức năng của DataSet. Bảng 1.12 mô tả một số thành phần cốt lõi của kiểu DataTable ngoài Rows và Columns.
  34. Các thành phần chính của kiểu DataTable. Thành phần Ý nghĩa CaseSensitive Cho biết chuỗi bên trong bảng có phân biệt hoa/thƣờng hay không. Giá trị mặc định là false. ChildRelations Trả về tập hợp của những quan hệ con cho DataTable này (nếu có) Constraints Đƣa ra tập hợp của những ràng buộc của bảng. Copy() Phƣơng thức sao chép mô hình và dữ liệu của một DataTable đã cho vào trong một thể hiện mới. DataSet Đƣa ra DataSet mà chứa bảng này (nếu có) DefaultView Đƣa ra một view mặc định của bảng. MinimumCapacity Đƣa ra hay thiết lập số lƣợng hàng ban đầu trong bảng (mặc định là 5). ParentRelations Đƣa ra tập hợp của những quan hệ cha cho DataTable này. PrimaryKey Thiết lập những cột mà có chức năng khóa chính cho bảng dữ liệu. RemotingFormat Cho phép định nghĩa cách DataSet xuất nội dung của nó ( nhị phân hay XML). TableName Thiết lập tên của bảng. Ví dụ: DataTable table = new DataTable(“SinhVien”); table.Columns.Add(new DataColumn(“MSSV”, Type.GetType(“Int32”)); table.Columns.Add(new DataColumn(“HoTen”, Type.GetType(“string”)); table.PrimaryKey = new DataColumn[] { table.Columns[“MSSV”] }; DataRow row = table.NewRow(); row[“MSSV”] = 123; row[“HoTen”] = “Nguyễn Văn A”; table.Rows.Add(row); 4.6. Data Binding 4.6.1. Giới thiệu DataBinding ASP.NET cung cấp cho rất nhiều điều khiển để cho phép hiển thị cũng nhƣ tiếp nhận thông tin từ ngƣời dùng. Có những điều khiển cho phép hiển thị những thông tin tĩnh (Static – tức là giá trị xác định đƣợc ngay khi lập trình), một số hiển thị đƣợc cả những thông tin động (Dynamic - tức là đƣợc tính toán khi chạy chƣơng trình). Để việc
  35. hiển thị thông tin động này một cách đơn giản và nhanh chóng, ASP.NET cung cấp một đặc tính gọi là "Data Binding" (kết nối dữ liệu). Data Binding là một kỹ thuật kết nối dữ liệu với những đối tƣợng. Sử dụng data binding, có thể nối dữ liệu trong một nguồn dữ liệu đến một đối tƣợng ngƣời dùng. Mọi việc thay đổi trên các đối tƣợng giao diện ngƣời dùng có thể trực tiếp đƣợc cập nhật vào nguồn dữ liệu. Từ "data" cũng cần phải đƣợc hiểu theo nghĩa rộng, nó không nhất thiết phải là cái gì đó liên quan đến Cơ sở dữ liệu nhƣ ta thƣờng nghĩ mà có thể là một thuộc tính, một mảng, một tập hợp, một danh sách, một trƣờng dữ liệu trong bảng cơ sở dữ liệu .hay tổng quát là một biểu thức trả về giá trị. Có hai kiểu binding dữ liệu đó là Simple Data Binding và Repeated Data Binding. Chúng ta quan tâm nhiều đến kiểu thứ hai – Repeated Data Binding - với nguồn dữ liệu đƣợc truy xuất từ cơ sở dữ liệu. 4.6.2. Data Binding a) Dạng kết nối dữ liệu đơn (Single Data Binding) Trong ASP.NET, có thể gắn một giá trị đơn lẻ vào trang đƣợc gọi là Single Data Binding. Cú pháp để gắn dữ liệu đơn vào trang nhƣ sau: Trong đó: biểu_thức có thể là một hằng, một biến, một hàm, một biểu thức hoặc có thể là một thuộc tính khác. Một số cách dùng dạng kết nối dữ liệu đơn: Hằng số: Hằng xâu: Biểu thức: Hàm : Thuộc tính khác: Có thể gắn kết tới một biểu thức, một biến, thuộc tính bất kỳ. Trong thủ tục Page_Load cần thêm lệnh this.DataBind() để thực sự gắn kết. Ví dụ: Tạo trang SimpleDataBinding.aspx minh họa dạng kết nối dữ liệu đơn giản. Phần mã lệnh thiết kế trang SimpleDataBinding.aspx trong đó có sử dụng dạng kết nối dữ liệu đơn giản với biến TransactionCount.
  36. There were transactions today. I see that you are using . Phần mã lệnh thực thi trang SimpleDataBinding.aspx.cs: public partial class SimpleDataBinding : System.Web.UI.Page { protected int TransactionCount; protected void Page_Load(object sender, EventArgs e) { TransactionCount = 10; this.DataBind(); } } b) Dạng kết nối dữ liệu có sự lặp lại (Repeated Data Binding) Có rất nhiều trƣờng hợp dữ liệu cần hiển thị là một danh sách (nhƣ mảng, bảng, DataReader, ) hay tổng quát là một tập hợp các mục (Collection Items ). Trong trƣờng hợp nhƣ vậy, hoàn toàn có thể dùng cơ chế DataBinding trong ASP.NET để gắn kết quả đó vào một điều khiển dạng danh sách (nhƣ ListBox, DropdownList, CheckboxList, ) để hiển thị mà không cần phải viết nhiều dòng code. Các điều khiển cho phép gắn kết dữ liệu thƣờng có ba thuộc tính với các ý nghĩa nhƣ sau: DataSource: Là thuộc tính để chỉ đến nguồn dữ liệu cần gắn kết. Nguồn dữ liệu này phải là một tập hợp. Ví dụ: DataTabe, Array, DataSourceID: Chỉ đến một đối tƣợng cung cấp nguồn dữ liệu. Có thể sử dụng hoặc thuộc tính DataSourceID hoặc DataSource nhƣng không đƣợc cả hai. DataTextField: Cho biết là gắn kết với trƣờng nào của mỗi mục dữ liệu. Ví dụ: Tạo trang ListDataBinding.aspx minh họa kết nối dữ liệu dạng Repeated Data Binding Phần mã lệnh thiết kế trang ListDataBinding.aspx.
  37. Phần mã lệnh thực thi trang ListDataBinding.aspx.cs: public partial class ListDataBinding : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { List fruit = new List (); fruit.Add("Kiwi"); fruit.Add("Pear"); fruit.Add("Mango"); fruit.Add("Blueberry"); fruit.Add("Apricot"); fruit.Add("Banana"); fruit.Add("Peach"); fruit.Add("Plum"); MyListBox.DataSource = fruit; MyDropDownListBox.DataSource = fruit; MyHTMLSelect.DataSource = fruit; MyCheckBoxList.DataSource = fruit; MyRadioButtonList.DataSource = fruit; // Activate the binding. this.DataBind(); } } Ví dụ: Tạo trang DataSetBinding.aspx liên kết dữ liệu ListBox với đối tƣợng ADO.NET là DataSet Phần mã lệnh thiết kế trang DataSetBinding.aspx:
  38. Phần mã lệnh thực thi trang DataSetBinding.aspx.cs. public partial class DataSetBinding : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { DataSet dsInternal = new DataSet(); dsInternal.Tables.Add("Users"); dsInternal.Tables["Users"].Columns.Add("Name"); dsInternal.Tables["Users"].Columns.Add("Country"); DataRow rowNew = dsInternal.Tables["Users"].NewRow(); rowNew["Name"] = "John"; rowNew["Country"] = "Uganda"; dsInternal.Tables["Users"].Rows.Add(rowNew); rowNew = dsInternal.Tables["Users"].NewRow(); rowNew["Name"] = "Samantha"; rowNew["Country"] = "Belgium"; dsInternal.Tables["Users"].Rows.Add(rowNew); rowNew = dsInternal.Tables["Users"].NewRow(); rowNew["Name"] = "Rico"; rowNew["Country"] = "Japan"; dsInternal.Tables["Users"].Rows.Add(rowNew); lstUser.DataSource = dsInternal.Tables["Users"]; lstUser.DataTextField = "Name"; lstUser.DataSource = dsInternal; lstUser.DataMember = "Users"; lstUser.DataTextField = "Name"; this.DataBind(); } 4.6.3. Các điều khiển Data Source a) Giới thiệu về DataSource Controls Sử dụng các đối tƣợng truy xuất dữ liệu (nhƣ DataReader) kết hợp với vòng lặp (while (Dr.DataRead() == true)) để duyệt và đọc toàn bộ bản ghi lấy về. Tuy nhiên một cách khác để đọc dữ liệu mà không phải viết code đó là dùng các điều khiển Data Source. Hiện tại ASP.NET cung cấp một số Data Source Controls sau đây:
  39. SqlDataSouce: Cho phép truy xuất tới bất kỳ nguồn dữ liệu sử dụng trình điều khiển (Provider) của ADO.NET. Bao gồm OleDb, SqlClient, ODBC, Oracle. (bài này sẽ sử dụng SqlDataSource để minh họa). ObjectDataSource: Truy xuất tới nguồn dữ liệu do ngƣời dùng tự định nghĩa. AccessDataSource: Truy xuất tới nguồn dữ liệu Access XmlDataSource: Truy xuất tới nguồn dữ liệu là file XML. Ý tƣởng của DataSource Control là: "chỉ việc đặt vài thông số kết nối và câu lệnh sql, sau đó có thể gắn vào Control này để lấy lại dữ liệu.". Việc gắn và lấy dữ liệu này thực hiện dễ dàng thông qua các thuộc tính khi khai báo Control. Tuy nhiên với DataSouce Control thì không chỉ có vậy, nó còn cho phép thực hiện các thao tác cập nhật khác nhƣ Update, delete, b) Sử dụng SqlDataSouce để chọn (Select) dữ liệu Tạo điều khiển SqlDataSouce: Để cho linh hoạt, thông số kết nối thƣờng đƣợc đặt trong file cấu hình (Web.config). Để đọc xâu kết nối này có thể thực hiện thông qua ký pháp dạng: . Ví dụ: Tạo một điều khiển SqlDataSouce để đọc toàn bộ nội dung của bảng tblUser trong cơ sở dữ liệu QLCB. Nội dung của file Web.config nhƣ sau: Tạo một SqlDataSource và select dữ liệu trong bảng tblUser " SelectCommand="Select * from tblUser" ID="DSND" >
  40. c) Sử dụng SqlDataSource để cập nhật dữ liệu Để cập nhật dữ liệu thì trong khai báo điều khiển SqlDatasource ta cần cung cấp cụ thể câu lệnh Update cho thuộc tính UpdateCommand. Khi thực hiện Update, thông thƣờng ta sẽ truyền giá trị vào thông qua các tham số. Do vậy, cần phải Add các tham số này trƣớc khi thực hiện thao tác Update. Ví dụ: Hiển thị bảng tblUser trong gridview, nhƣng có thêm chức năng cập nhật. Hình 4.11. Kết quả hiển thị trên Gridview Để có thể cập nhật đƣợc thực sự vào cơ sở dữ liệu, thực hiện mấy công việc sau: 1. Hiển thị cột Update, trong gridview: Đặt thuộc tính AutoGenerateEditButton="true". 2. Thêm thuộc tính UpdateCommand cho SqlDataSource 3. Truyền tham số và giá trị cho các trƣờng mà ta muốn cập nhật. 4. Gọi phƣơng thức Update của SqlDataSource. Trong đó 1) và 2) viết trong trang ASPX; 3) 4) viết trong sự kiện Row_Updating của GridView. " SelectCommand="Select TenDangNhap, MatKhau from tbluser" UpdateCommand="Update tblUser set MatKhau=@MatKhau where TenDangNhap=@TenDangNhap"
  41. public partial class Lession_15_DisplaytblUser : System.Web.UI.Page { protected void dgrDS_RowUpdating (object sender, GridViewUpdateEventArgs e) { string TenDN; string MKMoi; TenDN = e.NewValues ["TenDangNhap"].ToString (); MKMoi = e.NewValues ["MatKhau"].ToString (); DSND.UpdateParameters.Add ("MatKhau", MKMoi); DSND.UpdateParameters.Add ("TenDangNhap", TenDN); DSND.Update (); } } Trong thuộc tính UpdateCommand ở trên, ta có dòng: UpdateCommand="Update tblUser set MatKhau=@MatKhau where TenDangNhap=@TenDangNhap" Ở đây @MatKhau và @TenDangNhap đƣợc gọi là các tham số. Tham số này rất đa dạng, nó có thể là nội dung của một textbox hay cũng có thể do ta tạo ra tƣờng minh bằng câu lệnh dạng: SqlDataSource.UpdateCommand.Parameters.Add("Tên","Giá trị"). Trong trƣờng hợp này ta sẽ tạo bằng phƣơng thức Add, sau đó truyền giá trị là nội dung mà ngƣời dùng vừa sửa đổi. Khi ngƣời dùng sửa đổi nội dung và bấm vào nút "Update" (bên cạnh Gridview) thì Gridview sẽ Postback trở lại Server và kích hoạt sự kiện RowUpdating. Khi Postback (gửi về) Server, Gridview sẽ gửi kèm các thông tin về hàng (bản ghi) hiện đang đƣợc sửa chữa, cụ thể gồm: Các giá trị cũ (OldValues), các giá trị mới
  42. (NewValues), chỉ số của hàng đang sửa và có thể cả giá trị khóa của bản ghi (nếu trong Gridview ta đặt thuộc tính DataKeyNames) Để truy xuất đến các giá trị mới/cũ này ta viết: e.OldValues[Chỉ số / tên trƣờng], e.NewValues[Chỉ số hoặc tên trƣờng]. Để truy xuất đến giá trị khóa của bản ghi hiện hành, ta viết e.Keys[Chỉ số / hoặc tên trƣờng] (Ví dụ e.Keys[MaSanPham] ) Sau khi lấy đƣợc các giá trị này cần tạo ra parameters tƣơng ứng và gọi phƣơng thức Update() của điều khiển SqlDataSource. d) Xóa bản ghi trong cơ sở dữ liệu bằng SqlDataSource Để xóa bản ghi, ta cũng tiến hành tƣơng tự nhƣ khi cập nhật, đó là phải thêm thuộc tính DeleteCommand cho điều khiển SqlDataSource, tạo và truyền tham số trong sự kiện RowDeleting. Nhƣ vậy, nội dung trang Web ở trên sẽ đƣợc bổ sung thêm nhƣ sau: " SelectCommand="Select TenDangNhap, MatKhau from tbluser" UpdateCommand="Update tbluser set MatKhau=@MatKhau where TenDangNhap=@TenDangNhap" DeleteCommand="delete from tblUser where TenDangNhap=@TenDangNhap"> public partial class Lession_15_DisplaytblUser : System.Web.UI.Page { protected void dgrDS_RowDeleting (object sender, GridViewDeleteEventArgs e) { string TenDN = e.Keys ["TenDangNhap"].ToString (); ///Lấy giá trị khóa DSND.DeleteParameters.Add ("TenDangNhap", TenDN); DSND.Delete (); }
  43. protected void dgrDS_RowUpdating (object sender, GridViewUpdateEventArgs e) { string TenDN, MKMoi; TenDN = e.NewValues ["TenDangNhap"].ToString (); MKMoi = e.NewValues ["MatKhau"].ToString (); DSND.UpdateParameters.Add ("MatKhau", MKMoi); DSND.UpdateParameters.Add ("TenDangNhap", TenDN); DSND.Update (); } } Thứ tự thêm tham số phải giống nhƣ thứ tự sử dụng tham số trong thuộc tính UpdateCommand, DeleteCommand của SqlDataSource. 4.7. Các điều khiển liên kết dữ liệu 4.7.1. Điều khiển GridView GridView có lẽ là một điều khiển trình diễn dữ liệu quan trọng nhất của ASP.NET. Nó cho phép gắn và hiển thị dữ liệu ở dạng bảng, trong đó mỗi hàng là một bản ghi, mỗi cột ứng với một trƣờng dữ liệu. Ngoài việc hiển thị, GridView còn có rất nhiều tính năng khác mà trƣớc đây ngƣời ta phải viết rất nhiều dòng code mới có đƣợc. Ví dụ: định dạng, phân trang, sắp xếp, sửa đổi, xóa dữ liệu. GridView có thể gắn kết dữ liệu với các nguồn nhƣ DataReader, SqlDataSource, ObjectDataSource hay bất kỳ nguồn nào có cài đặt System.CollectionsEnumerable. a) Các thuộc tính và cột thuộc tính GridView ngoài việc hiển thị thuần túy các trƣờng của một nguồn dữ liệu, nó còn cho phép hiển thị dƣới các hình thức khác (ví dụ dƣới dạng nút, dạng HyperLink, dạng checkbox ), các cột khác bổ trợ cho việc thao tác dữ liệu nhƣ Select, Update, Delete hoàn toàn có thể tùy biến trong GridView. Để chỉnh sửa các cột dạng này, click chọn "smart tag" của GridView và chọn "Edit Field" hoặc chọn thuộc tính Columns của GridView trong cửa sổ thuộc tính. Loại cột Mô tả BoundField Hiển thị giá trị của một trƣờng thuộc nguồn dữ liệu. ButtonField Hiển thị một nút lệnh cho mỗi mục trong GridView. Nút này cho phép ra các nút tùy biến kiểu nhƣ Add hay Remove. CheckBoxField Hiển thị một checkbox ứng với mỗi mục trong GridView. Cột này thƣờng đƣợc dùng để hiển thị các trƣờng kiểu Boolean (Yes/No).
  44. CommandField Hiển thị các nút lệnh đã đƣợc định nghĩa sẵn để thực hiện các thao tác select, edit, hay delete. HyperLinkField Hiển thị giá trị của một trƣờng dƣới dạng siêu liên kết (hyperlink). Loại cột này cho phép gắn một trƣờng thứ hai vào URL của siêu liên kết. ImageField Hiển thị một ảnh ứng với mỗi mục trong GridView. TemplateField Hiển thị nội dung tùy biến của ngƣời dùng cho mỗi mục dữ liệu trong GridView, theo nhƣ mẫu định sẵn. Loại cột này cho phép ta tạo ra các cột tùy biến. Các thuộc tính: Thuộc tính Mô tả GridLines Ẩn, hiện các đƣờng viền của GridView. ShowHeader Cho phép Hiện/ ẩn phần Header ShowFooter Cho phép Hiện/ ẩn phần Footer PageSize Get/Set cho biết mỗi trang chứa bao nhiêu dòng. PageCount Cho biết số trang của nguồn dữ liệu mà nó gắn kết PageIndex Get/Set chỉ số của trang đang đƣợc hiển thị AllowPaging Có cho phép phân trang không ( true = có) AllowSorting Có cho phép sắp xếp không (true=có) AutoGenerateColumns Có tự động sinh ra các cột ứng với các cột trong nguồn dữ liệu hay không ? Mặc định = true (có) AutoGenerateDeleteButton Tự động tạo ra cột Delete (true = tự động) AutoGenerateUpdateButton Tự động tạo ra cột Update (true = tự động) AutoGenerateSelectButton Tự động tạo ra cột Select (true = tự động) EditIndex Đặt hàng nào đó về chế độ edit. EditIndex = 2 hàng thứ 3 (SelectedIndex) (chỉ số 2) sẽ về chế độ edit. Nếu đặt EditIndex = -1 thì sẽ thoát khỏi chế độ Edit. SelectedIndex Trả về chỉ số của dòng đang chọn Rows Một tập hợp chứa các hàng của GridView. Columns Một tập hợp chứa các cột của GridView. b) Các style áp dụng cho GridView. GridView rất linh hoạt trong việc trình bày dữ liệu, nó cho phép ta định dạng các phần thông qua style. Ví dụ ta có thể định dạng cho phần Header, Footer, các mục dữ liệu, các hàng chẵn-lẻ v.v
  45. Bảng dƣới đây sẽ giải thích rõ ý nghĩa một số thuộc tính. Thuộc tính Style Mô tả AlternatingRowStyle Style áp dụng cho các hàng dữ liệu chẵn-lẻ trong GridView. Khi đặt thuộc tính này thì các hàng sẽ đƣợc hiển thị với định dạng luân phiên giữa RowStyle và AlternatingRowStyle. EditRowStyle Style để hiển thị hàng hiện đang đƣợc sửa (Edit). FooterStyle Style áp dụng cho phần Footer. HeaderStyle Style áp dụng cho phần Header. PagerStyle Style áp dụng cho phần phân trang (các trang >). RowStyle Style áp dụng cho các hàng dữ liệu trong GridView Control. Khi AlternatingRowStyle đƣợc thiết lập thì sẽ áp dụng luân phiên giữa RowStyle và AlternatingRowStyle. SelectedRowStyle Style áp dụng cho hàng đang đƣợc chọn (Selected)của GridView. c) Các sự kiện GridView có rất nhiều sự kiện quan trọng, các sự kiện này khi kích hoạt sẽ cung cấp cho ta những thông tin hữu ích trong quá trình xử lý. Ví dụ khi click nút Update, nó sẽ kích hoạt sự kiện Updating và trả về cho các giá trị mà ngƣời dùng vừa sửa . Dƣới đây là bảng tổng hợp một số sự kiện hay dùng nhất. Tên sự kiện Mô tả PageIndexChanged Xuất hiện khi ta click chọn các nút ( >) trong hàng phân trang. PageIndexChanging Xuất hiện khi ngƣời dùng click chọn các nút ( >) trong hàng phân trang nhƣng TRƢỚC khi GridView thực hiện việc phân trang RowCancelingEdit Xuất hiện khi nút Cancel đƣợc click nhƣng trƣớc khi thoát khỏi chế độ Edit. RowCommand Xuất hiện khi một nút đƣợc click. RowCreated Xuất hiện khi một hàng mới đƣợc tạo ra. Thƣờng đƣợc sử dụng để sửa nội dung của hàng khi nó vừa đƣợc tạo ra. RowDataBound Xuất hiện khi một hàng dữ liệu đƣợc gắn vào GridView. Tại đây ta có thể sửa đổi nội dung của hàng đó. RowDeleted Xuất hiện khi nút Delete của một hàng đƣợc click, nhƣng sau khi GridView đã delete bản ghi từ nguồn.
  46. RowDeleting Xuất hiện khi nút Delete đƣợc click nhƣng trƣớc khi GridView xóa bản ghi từ nguồn. Tại đây có thể Cancel việc Delete. RowEditing Xuất hiện khi nút Edit đƣợc click, nhƣng trƣớc khi GridView về chế độ sửa. RowUpdated Xuất hiện khi nút Update đƣợc click, nhƣng sau khi GridView update hàng dữ liệu. RowUpdating Xuất hiện khi nút Update đƣợc click, nhƣng trƣớc khi GridView update hàng dữ liệu. SelectedIndexChanged Xuất hiện khi nút Select của hàng đƣợc click nhƣng sau khi GridView xử lý xong thao tác Select. SelectedIndexChanging Xuất hiện khi nút Select của hàng đƣợc click nhƣng trƣớc khi GridView xử lý xong thao tác Select. Sorted Xuất hiện khi Hyperlink (tiêu đề cột) đƣợc click, nhƣng sau khi GridView thực hiện việc sắp xếp. Sorting Xuất hiện khi Hyperlink (tiêu đề cột) đƣợc click, nhƣng trƣớc khi GridView thực hiện việc sắp xếp. Sự kiện này khi xảy ra, nó sẽ cung cấp thông tin về tên cột vừa đƣợc click. Dựa vào đó ta có thể thực hiện việc sắp xếp. d) Các phƣơng thức Tên phƣơng thức Mô tả DataBind() Gắn kết dữ liệu giữa GridView và nguồn dữ liệu (đặt các thuộc tính DataSource, DataTextField hoặc DataSourceID. DeleteRow(int) Xóa một dòng trong GridView UpdateRow(int i, bool Valid) Cập nhật một dòng trong GridView. Sort(Biểu thức sx, hƣớng sx) Sắp xếp dựa trên biểu thức và hƣớng. e) Các tính năng hỗ trợ của GridView - Phân trang Để thực hiện phân trang, cần đặt thuộc tính AllowPaging = True. Khi phân trang, có thểtùy biến hiển thị các trang (hiển thị dạng các số 1 2 3 hay mũi tên >) bằng cách đặt các thuộc tính con trong PagerSettings. "
  47. SelectCommand="SELECT * FROM tblUser"> Nếu gắn kết gridview với DataReader/ DataTable/ DataSet thì cần phải chỉ định rõ chỉ số trang cần hiển thị khi sự kiện PageIndexChanging đƣợc kích hoạt, cụ thể nhƣ sau: public partial class Lession_18_PagingwithDataReaderBinding : System.Web.UI.Page { protected void NapDuLieu() { SqlConnection Cn = new SqlConnection (); Cn.ConnectionString=ConfigurationManager.ConnectionStrings ["QLCBConnectionString"].ToString(); Cn.Open (); SqlDataAdapter Da = new SqlDataAdapter ("Select * from tblUser", Cn); DataSet Ds = new DataSet (); Da.Fill (Ds, "DSND"); dgrDSND.DataSource = Ds.Tables ["DSND"]; dgrDSND.DataBind (); Ds.Dispose (); Da.Dispose (); Cn.Close (); }
  48. protected void cmdHienThi_Click (object sender, EventArgs e) { NapDuLieu (); //Gọi hàm nạp dữ liệu } protected void dgrDSND_PageIndexChanging (object sender, GridViewPageEventArgs e) { dgrDSND.PageIndex = e.NewPageIndex; // Đặt lại chỉ số trang cần hiển thị NapDuLieu (); } } - Tính năng tự động sắp xếp Tính năng này cho phép dữ liệu trong GridView sẽ tự động sắp xếp theo giá trị của cột. Có thể sắp xếp theo chiều tăng (Asscending) hoặc giảm (Descending). Để bật tính năng này, cần đặt thuộc tính AllowSorting = true trong GridView. Khi ngƣời dùng click chuột vào một cột tiêu đề nào đó của GridView thì sự kiện Sorting sẽ đƣợc kích hoạt, tại đây ta cần phải chỉ rõ cho GridView biết là sắp theo cột nào (SortExpression ) và theo chiều tăng hay giảm (SortDirection). Ví dụ: Hiện thị danh sách ngƣời dùng trong bảng tblUser, khi ngƣời dùng click vào một cột thì sắp theo chiều tăng dần. " SelectCommand="SELECT * FROM tblUser"> public partial class Lession_18_AllUserwithPaging : System.Web.UI.Page { protected void dgrDSND_Sorting (object sender, GridViewSortEventArgs e) { e.SortDirection= SortDirection.Descending; } }
  49. f) Các mẫu hiển thị Template ASP.NET cung cấp sẵn một số Template (mẫu) để hiển thị GridView cũng khá đẹp. Vì vậy có thể sử dụng ngay các template này khi xây dựng ứng dụng. Cách thức chọn template cho GridView nhƣ sau: - Mở trang ở chế độ Design - Chọn GridView và chọn smart tag, tiếp theo chọn AutoFormat Hình 4.13. Chọn định dạng cho Grodview Chọn Format trong danh sách. Sau khi chọn Template, Asp sẽ tự động tạo ra các thuộc tính (thẻ) tƣơng ứng trong GridView, tại đây có thể tiếp tục tùy biến thêm theo nhƣ ý muốn. - Tạo các cột tùy biến HyperLink, BoundColunm + Tạo cột BoundField thủ công Để tạo các cột thủ công, cần đặt thuộc tính AutoGenerateColumns = "Fase", sau đó soạn thủ công các cột trong cửa số Edit Columns. Ví dụ: Hiển thị danh sách ngƣời dùng nhƣng các cột tạo thủ công. " SelectCommand="SELECT * FROM tblUser">
  50. + Tạo một cột hyperlink Hiển thị danh sách ngƣời dùng (bảng tbluser) trong đó có cột "Chi tiết" để khi click chuột vào hyperlink này thì chuyển đến trang hiển thị chi tiết ngƣời dùng. Trong ASP.NET, GridView có khả năng hiển thị (render) các trƣờng có chứa HyperLink thành các thẻ trên trình duyệt. Do vậy, cần phải tạo một cột mới có chứa sẵn Hyperlink sau đó "Chèn" trƣờng này vào cột Hyperlink của GridView. Trong SQL, thông thƣờng trong câu lệnh SELECT chỉ chọn các trƣờng sẵn có trong bảng cơ sở dữ liệu, tuy nhiên hoàn toàn có thể tạo ra một cột mới kiểu nhƣ sau: SELECT Ten + Ho as HoVaTen FROM Ten, Ho là 2 trƣờng của bảng, HoVaTen là một cột mới (Do ta tạo ra ngay trong câu lệnh SELECT, còn trong bảng cơ sở dữ liệu thì không có trƣờng này) Hoặc SELECT TenHang, NgayXua, SoLuong, DonGia, SoLuong * DonGia As ThanhTien Trƣờng ThanhTien là một trƣờng mới. Giá trị của nó bằng giá trị SoLuong * DonGia của bản ghi hiện tại. Để tạo cột hiển thị đƣợc HyperLink, GridView cung cấp thẻ : " SelectCommand="SELECT TenDangNhap, HoVaTen, MatKhau, 'UserDetail.aspx?TenDangNhap=' + TenDangNhap as ChiTiet FROM tblUser">
  51. + Tạo cột Image Tƣơng tự nhƣ cột HyperLink, GridView cũng có một cột để hiển thị hình ảnh (ImageField) nếu trƣờng dữ liệu gắn với nó chứa đƣờng dẫn đến ảnh nằm trong ứng dụng. Để tạo cột cho phép hiển thị Image, dùng thẻ " SelectCommand="SELECT TenDangNhap, HoVaTen, MatKhau, HinhAnh FROM tblUser">
  52. - Tạo và xử lý các cột Select, Edit, Delete, Update + Thêm cột Select, Edit - Update, Delete GridView không chỉ hiển thị đƣợc các bảng dữ liệu mà còn hỗ trợ rất tốt trong việc chỉnh sửa và xóa dữ liệu. Đặc biệt khi nguồn dữ liệu là SqlDataSource thì việc sửa và xóa hoàn toàn tự động, không cần phải viết bất kỳ dòng code nào. Để bật tính năng này, cần bổ sung thêm thuộc tính vào GridView với giá trị là true cho AutoGenerateSelectColum, AutoGenerateEditColum, AutoGenerateDeleteColum. Xét ví dụ sau: " SelectCommand="SELECT TenDangNhap, HoVaTen, MatKhau FROM tblUser"> Hình 4.14. Hiển thị các cột lệnh
  53. + Cập nhật dữ liệu Ví dụ: Xây dựng trang Web cho phép hiển thị và cập nhật (Update) trƣờng Họ và tên và Mật khẩu của bảng tblUser: Các bƣớc cần tiến hành: - Tạo một nguồn dữ liệu SqlDataSource - Thêm thuộc tính UpdateCommand với câu lệnh cập nhật Sql. - Tạo GridView và đặt thuộc tính DataKeyNames = "Tên trƣờng Khóa của bảng cơ sở dữ liệu " - Gắn kết GridView với SqlDataSource bằng cách đặt DataSourceID của GridView = ID của SqlDataSource. " UpdateCommand= "UPDATE tblUser SET MatKhau=@MatKhau, QuyenHan=@QuyenHan WHERE TenDangNhap=@TenDangNhap"> Hình 4.15. Kết quả sau khi chạy
  54. Khi sử dụng nguồn dữ liệu là SqlDataSource và trong câu lệnh Update/Delete nếu ta đặt tên các tham số giống với tên của các trƣờng dữ liệu (ví dụ MatKhau=@MatKhau) thì SqlDataSource sẽ tự động tạo các tham số sau đó truyền giá trị mà ngƣời dùng vừa mới nhập. Vì vậy không cần phải viết các câu lệnh cập nhật tƣờng minh. Trang Code: Không phải viết vì khai báo ở trên sẽ tự động cập nhật + Xóa dữ liệu Ví dụ : Xây dựng trang Web cho phép xóa bản ghi trực tiếp trên GridView. Việc xóa hoàn toàn tƣơng tự nhƣ Update. Tức là ta cũng cần phải thêm thuộc tính DeleteCommand vào trong SqlDataSource. cụ thể nhƣ sau: " SelectCommand="SELECT TenDangNhap, HoVaTen, MatKhau FROM tblUser" DeleteCommand="Delete tblUser where TenDangNhap = @TenDangNhap"> Hình 4.16. Xóa trực tiếp trên GridView
  55. g) Tạo template với GridView Khả năng trình diễn dữ liệu rất mạnh của GridView, nó có thể phân trang tự động, sắp xếp tự động và cập nhật dữ liệu tự động Tuy nhiên, trong một số trƣờng hợp cụ thể vẫn rất cần phải có sự trình bày linh hoạt hơn, ví dụ: muốn trình bày dữ liệu theo chiều dọc chẳng hạn. v v GridView và các điều khiển khác đều có cơ chế để hỗ trợ khả năng tùy biến rất cao đó là TEMPLATE. Template là các mẫu định sẵn, mẫu này do lập trình viên tự thiết kế. Trong mẫu này có thể thêm bất cứ thẻ HTML hay thẻ Server hợp lệ. Mỗi lần xử lý một mục dữ liệu (một bản ghi) thì hệ thống sẽ tự động đƣa mục dữ liệu này vào bên trong mẫu. Trong ASP.NET có rất nhiều điều khiển hỗ trợ khả năng tùy biến bằng Templates. Một số điều khiển phổ biến hỗ trợ Template bao gồm: GridView, DataGrid, DataList, Repeater, Listview Các điều khiển đều có một số phần hiển thị tƣơng tự nhau: Nhƣ phần tiêu đề (Header), phần nội dung dữ liệu (DataItem) và phần chân trang (Footer). Ý nghĩa cụ thể của từng phần này nhƣ sau: HeaderTemplate: Là phần cho phép định dạng tiêu đề trƣớc nội dung hiển thị. Thƣờng là tên các trƣờng trong cơ sở dữ liệu, ItemTemplate: Là phần cho phép định dạng cách thức hiển thị mục dữ liệu (bản ghi). Phần này đƣợc tạo ra mỗi khi một dòng dữ liệu đƣợc gắn kết vào điều khiển. AlternateTemplate: Phần này cho phép định dạng cách thức hiển thị của phần tử thuộc hàng chẵn. FooterTemplate: Cho phép định dạng chân trang sau nội dung hiển thị. Khi sử dụng Template, thƣờng chúng ta có mong muốn là hiển thị một số trƣờng dữ liệu nào đấy. Vì vậy, ASP.NET cung cấp một hàm gọi là Eval("Tên_Mục/Trƣờng dữ liệu") cho phép lấy dữ liệu của một trƣờng thuộc bản ghi hiện hành. Giá trị của hàm Eval() này đƣợc đƣa vào trong thẻ hiện hành thông qua cơ chế DataBind, kiểu nhƣ sau: Họ và tên: Ví dụ: Tạo một trang Web hiển thị danh sách Họ và tên ngƣời dùng trong bảng tblUser sử dụng Template của GridView. " SelectCommand="SELECT * FROM tblUser">
  56. Ví dụ : Đặt họ tên vào các TextBox '> Ví dụ: Hiển thị họ tên và TrangThai. Trong đó TrangThai đƣợc đặt trong ngoặc ngay sau họ và tên. ( ) Ví dụ: Hiển thị họ tên và ảnh
  57. " SelectCommand="SELECT * FROM tblUser"> '/> Ví dụ: Hiển thị các trƣờng HoVaTen, MatKhau, Hình ảnh trên GridView, mỗi trƣờng hiển thị trên một cột và Họ tên chữ đậm. " SelectCommand="SELECT * FROM tblUser">
  58. ' Width="100px" Height="100px" /> Ví dụ: Hiển thị dữ liệu trong một cột Họ và tên: Tên đăng nhập: Quyền hạn : Trạng thái: Hình ảnh : ' /> Ví dụ : Cập nhật hồ sơ cán bộ (cập nhật trƣờng "Bản thân") Họ và tên: Mã Cán bộ: Ngày sinh : Địa chỉ:
  59. Bản thân : Họ và tên: Mã Cán bộ: Ngày sinh : Địa chỉ: Bản thân : '> 4.7.2. Điều khiển DataList DataList cho phép ta hiển thị dƣới dạng danh sách. Danh sách này có thể chia làm nhiều cột. DataList cho phép tùy biến các mục tƣơng tự nhƣ GridView Ví du: Hiển thị ảnh " SelectCommand="SELECT * FROM tblUser"> Họ và tên: Quyền hạn : ' />
  60. Hình 4.17. Kết quả sau khi chạy 4.7.3. Điều khiển Repeater Repeater cũng là một điều khiển có khả năng hiển thị dữ liệu dƣới dạng danh sách. Khi đƣợc gắn với nguồn dữ liệu, nó sẽ lần lƣợt thực thi nội dung nằm trong phần Template mỗi khi một bản ghi đƣợc đọc từ nguồn. Tuy điều khiển này không có khả năng phân trang, sắp xếp nhƣ GridView, nó là một điều khiển chiếm ít tài nguyên của hệ thống (vì vậy đƣợc gọi là điều khiển Light- weight), do đó có thể dùng trong những trƣờng hợp mà ở đó tài nguyên đóng vai trò quan trọng. Repeater cho phép tùy biến các mục tƣơng tự nhƣ GridView và DataList, đó là sử dụng Template. Ví dụ: Hiển thị họ tên và ảnh minh họa ngƣời dùng trong bảng tblUser sử dụng điều khiển Repeater. " SelectCommand="SELECT * FROM tblUser"> Họ và tên: <asp:Image runat="server"
  61. ImageUrl=' ' Width="100px" Height="100px" /> 4.7.4. DetailView Điều khiển này cho phép thay đổi, thêm mới hay xoá dữ liệu nhƣ một bản ghi cơ sở dữ liệu và nó cho phép chuyển sang trang tiếp theo hay quay lại trang trƣớc thông qua thiết lập dữ liệu. Dùng để trình bày dữ liệu là một mẫu tin tại một thời điểm, xem ví dụ dƣới đây qua đó nắm vững cách sử dụng đối tƣợng này.
  62. " SelectCommand="SELECT ProductID, ProductName, UnitPrice FROM Products" UpdateCommand="UPDATE Products SET ProductName=@ProductName, UnitPrice=@UnitPrice WHERE ProductID=@ProductID" InsertCommand="INSERT Products (ProductName, UnitPrice) VALUES (@ProductName, @UnitPrice)" DeleteCommand="DELETE Products WHERE ProductID=@ProductID" OnInserted="SqlDataSource1_Inserted" > 4.7.5. FormView Dùng để trình bày dữ liệu là một mẫu tin tại một thời điểm. Tƣơng tự nhƣ DetailsView nhƣng cho phép trình bày dữ liệu theo các mẫu tùy chọn (custom temnplates). Xem ví dụ dƣới đây qua đó nắm vững cách sử dụng đối tƣợng này. " SelectCommand="SELECT * FROM Products"> " SelectCommand="SELECT * FROM Products WHERE ProductID=@ProductID">
  63. In Stock: On Order: Reorder: 4.7.6. ListView Dùng để trình bày dữ liệu là một mẫu tin tại một thời điểm. Listview nhƣng cho phép trình bày dữ liệu theo các mẫu tùy chọn (custom temnplates), Listview hổ trợ phân nhóm, phân trang, thêm, xoá, cập nhật và sắp xếp dữ liệu.Xem ví dụ dƣới đây qua đó nắm vững cách sử dụng đối tƣợng này /> 4.8. Bài tập 1. Tạo một ứng dụng Web cơ bản cho phép quản lý danh sách nhân viên và phòng ban. Gồm hai form cơ bản: - Default.aspx: trang này cho phép gọi các trang quản lý nhân viên và phòng ban - qlnv.aspx: cho phép hiển thị danh sách nhân viên, ngoài ra có chức năng cập nhật thông tin của nhân viên. Danh sách nhân viên này có hỗ trợ chức năng phân trang.
  64. - qlpb.aspx: cho phép chọn một phòng ban và xem danh sách nhân viên trong phòng ban, ngoài ra hiển thị thông tin của ngƣời phụ trách phòng ban chính phòng ban. Hƣớng dẫn: 1.1. Cơ sở dữ liệu 1.2. Giao diện Giao diện trang default.aspx Giao diện trang qlnv.aspx
  65. Giao diện trang qlpb.aspx 2. Tạo một ứng dụng Web cơ bản cho phép quản lý album bài hát: - Cho phép user xem các bài hát theo các mục nhƣ: tên tác giả, thể loại, album - User có thể tạo mới một album từ các bài hát đã có trong danh sách bài hát Ứng dụng gồm 2 trang chính nhƣ sau: - SongManaging.aspx: trang này cho phép ngƣời dùng chọn xem các bài hát theo tên tác giả, thể loại và các album có sẵn. Giao diện của trang Web đơn giản nhƣ sau: Giao diện trang SongManaging.aspx Minh họa cách thao tác trên trang SongManaging.aspx
  66. - Album.aspx: Cho phép user tạo album mới với tên gọi và danh sách các bài hát đã chọn trong trang SongManaging.aspx. Giao diện trang Album.aspx Hƣớng dẫn: 2.1. Cơ sở dữ liệu: tạo cơ sở dữ liệu SongAlbum có các bảng nhƣ sau: - Albums: chứa danh sách các album - Songs: chứa danh sách các bài hát - AlbumSong: chứa danh sách các bài hát thuộc album - Artist: danh sách các nghệ sỹ - Genres: thể loại Bảng Album Bảng AlbumSong
  67. Bảng Artist Bảng Genres Bảng Song 3. Để quản lý bán sách của một cửa hàng trên mạng ngƣời ta xây dựng một Website đƣợc thiết kế giao diện nhƣ sau: Dữ liệu đƣợc lƣu trữ trong 2 bảng Sach và Thanhvien gồm các trƣờng nhƣ sau: Sach (id, Tensach, Tacgia, Nhaxb, Namxb, Sotrang, Mota, Hinhanh) Thanhvien (Tentruynhap, Matkhau, Hoten, Email, Quyen) 3.1. Sử dụng phần mềm Microsoft SQLServer tạo ra các bảng dữ liệu có cấu trúc nhƣ trên (với trƣờng và độ rộng phù hợp).
  68. 3.2. Thiết kế Website có cấu trúc nhƣ trên với hình ảnh phù hợp 3.3. Hãy sử dụng Visual studio.net xây dựng các trang Web cho các mục: - Sản phẩm: trang “Thêm - Sửa” dùng để nhập mới, sửa đổi hoặc xóa một sách; trang “Tìm kiếm” dùng để tìm kiếm một sách theo tên; trang “Danh sách” dùng để xem danh sách các cuốn sách. - Hệ thống: trang “Danh sách thành viên” để xem danh sách thành viên; trang “Thêm - Sửa thành viên” dùng để nhập mới, sửa đổi hoặc xóa một thành viên. 3.4. Xây dựng lớp, đối tƣợng, phƣơng thức, sự kiện xử lý cho mục đăng nhập hệ thống sao cho nếu username và password đúng sẽ cho đăng nhập hệ thống và trang thái sẽ đƣợc thay đổi theo tên ngƣời dùng, ngƣợc lại thì sẽ báo lỗi, trạng thái là chƣa đăng nhập. 4. Để quản lý bán điện thoại của một cửa hàng trên mạng ngƣời ta xây dựng một Website đƣợc thiết kế nhƣ sau: 4.1. Thiết kế Website có cấu trúc nhƣ trên (gồm: Banner, Menu trái, Contents, Menu phải) với dữ liệu ảnh đã cho. 4.2. Dùng ngôn ngữ lập trình C# để lập trình chức năng Nhập cho phép nhập mới sản phẩm điện thoại vào cơ sở dữ liệu SQL Server gồm các thông tin theo form sau:
  69. 4.3. Sử dụng Visual Studio xây dựng các trang Web cho mục Điện Thoại: trang Tìm kiếm dùng để tìm kiếm sản phẩm điện thoại theo giá, trang Hiển Thị dùng để xem danh sách các sản phẩm. 5. Để quản lý bán mỹ phẩm của một cửa hàng trên mạng ngƣời ta xây dựng một Website đƣợc thiết kế nhƣ sau: 5.1. Thiết kế Website có cấu trúc nhƣ trên (gồm: Banner, Menu trái, Contents, Menu phải) với dữ liệu ảnh đã cho. 5.2. Dùng ngôn ngữ lập trình C# để lập trình chức năng Xóa cho phép xóa một sản phẩm (gồm các thông tin Mã mỹ phẩm, Tên mỹ phẩm, Hãng sản xuất, Cách dùng, Đơn giá, Hình ảnh) trong cơ sở dữ liệu SQL Server theo form sau: 5.3. Sử dụng Visual Studio và SQL Server xây dựng trang Nhập/Sửa/Xóa Thành Viên dùng để nhập mới, sửa đổi hoặc xóa thành viên. Biết rằng thông tin về thành viên gồm: Tên đăng nhâp, Mật khẩu, Họ tên, Số điện thoại, Địa chỉ, Email. 6. Để quản lý bán mũ bảo hiểm của một cửa hàng trên mạng ngƣời ta xây dựng một Website đƣợc thiết kế nhƣ sau:
  70. 6.1. Thiết kế Website có cấu trúc nhƣ trên (gồm: Banner, Menu trái, Contents, Menu phải) với dữ liệu ảnh đã cho. 6.2. Dùng ngôn ngữ lập trình C# để lập trình chức năng Sửa cho phép sửa đổi thông tin của sản phẩm mũ trong cơ sở dữ liệu SQL Server theo form sau: 6.3. Sử dụng Visual Studio xây dựng các trang Web cho mục Sản Phẩm: trang Xóa dùng để xóa sản phẩm, trang Tìm kiếm dùng để tìm kiếm sản phẩm theo màu sắc. 7. Bài tập tổng hợp Dự án Website “Nƣớc hoa - mỹ phẩm” cho công ty ABC với mục tiêu: giới thiệu sản phẩm, cho phép đặt hàng và thanh toán trực tuyến các sản phẩm nƣớc hoa, mỹ phẩm của các thƣơng hiệu nổi tiếng mà ngƣời dùng ƣa chuộng. Ngoài ra hệ thống còn cung cấp công cụ giúp quản trị nhƣ: Quản trị cấu hình, quản trị ngƣời dùng, quản trị sản phẩm, hỗ trợ trực tuyến, quản trị liên hệ
  71. Danh sách chức năng của Website: 1. Trang chủ 2. Trang sản phẩm 3. Trang chi tiết sản phẩm 4. Module quản lý - Cấu hình hệ thống - Quản trị ngƣời dùng - Quản trị danh mục trang - Liên hệ, phản hồi 5. Tin tức - Quản trị nhóm tin - Quản trị danh sách tin 6. Quản trị sản phẩm, khách hàng, đơn hàng - Quản trị nhãn hiệu sản phẩm - Quản trị nhóm sản phẩm - Quản trị danh sách sản phẩm - Quản lý khách hàng - Quản lý đơn hàng bán lẻ - Quản lý đơn hàng mua chung - Phản hồi sản phẩm 7. Quản trị hỗ trợ - Nhóm hỗ trợ - Danh sách nhân sự hỗ trợ Giao diện Website: - Giao diện trang chủ
  72. CHƢƠNG 5: WEB SERVICES 5.1. Giới thiệu về Web Services Một dịch vụ Web (Web Services) là một hệ thống phần mềm đƣợc xây dựng để hỗ trợ khả năng tƣơng tác giữa các máy tính trên mạng (theo Wide Web Consortium). Nó cung cấp một giao tiếp đƣợc mô tả theo một định dạng chung thƣờng gọi là ngôn ngữ mô tả dịch vụ Web (Web Services Description Language – WSDL). Các hệ thống khác thực hiện tƣơng tác với dịch vụ Web thông qua giao thức SOAP (Simple Object Access Protocol). Đây là giao thức giúp trao đổi thông tin sử dụng HTTP kết hợp với việc sử dụng đặc tả XML cùng với một số chuẩn khác. Nhƣ vậy, mục đích chính của việc phát triển của dịch vụ Web là cho phép giao tiếp và trao đổi các chức năng, thông tin, dữ liệu giữa các ứng dụng một cách dễ dàng mà không cần quan tâm đến môi trƣờng phát triển, ngôn ngữ lập trình bởi tất cả đã đƣợc quy về một định dạng chung. Bản chất của Web Services là một tập hợp các đối tƣợng, các phƣơng thức đƣợc thực thi và công bố trên mạng để có thể đƣợc gọi từ xa thông qua các ứng dụng khác. 5.2. Kiến trúc và các thành phần Web Services Công nghệ Web Services ra đời dựa trên sự kết hợp các nền tảng công nghệ sẵn có trƣớc đó. Nó là sự tích hợp các ứng dụng dựa trên Web sử dụng các chuẩn mở nhƣ XML, SOAP, WSDL, UDDI. Trong đó, XML đƣợc sử dụng để mô tả dữ liệu, SOAP đóng vai trò giao thức truyền tải dữ liệu, WSDL mô tả cho dịch vụ Web và UDDI liệt kê danh sách các dịch vụ Web đang hoạt động. a) XML – Extensible Markup Language XML do W3C đề ra và đƣợc phát triển từ SGML. XML là một ngôn ngữ đánh dấu mở rộng với cấu trúc do ngƣời dùng định nghĩa. Về hình thức, XML có cú pháp tƣơng tự HTML, nhƣng không tuân theo một đặc tả quy ƣớc nhƣ HTML. Ngƣời sử dụng hay các chƣơng trình có thể quy ƣớc định dạng các thẻ XML, ngoài ra không chứa bất cứ thông tin nào khác về cách sử dụng hay hiển thị những thông tin ấy. Web Services là sự kết hợp của nhiều thành phần khác nhau và nó hỗ trợ tƣơng tác giữa các hệ thống đƣợc cài đặt trên các môi trƣờng khác nhau. Do đó, cần sử dụng một
  73. dạng tài liệu có thể giúp giải quyết vấn đề tƣơng thích và XML hoàn toàn phù hợp với yêu cầu trên. Nó đã trở thành nền tảng cho việc xây dựng các Web Services. XML có hai vai trò chính: - Trao đổi dữ liệu trong hệ thống sử dụng Web Services. - Mô tả các giao thức sử dụng trong dịch vụ Web. b) SOAP – Simple Object Access Protocol SOAP (Simple Object Access Protocol) là giao thức dùng để truy xuất thông tin từ Web Services thông qua một dạng thông điệp chung. SOAP đƣợc Microsoft đề xuất vào năm 1998. Hiện nay, nó thuộc quyền quản lý và cải tiến bởi tổ chức W3C. SOAP là một giao thức dựa trên nền tảng XML, mô tả cách định dạng, đóng gói thông tin của các thông điệp và trao đổi chúng thông qua mạng mà không phụ thuộc vào bất kỳ ngôn ngữ hay môi trƣờng thực thi nào. Đơn vị trao đổi thông tin cơ bản của giao thức SOAP là thông điệp SOAP (SOAP Message). Mỗi thông điệp SOAP sẽ đƣợc chỉ định bởi một thẻ root chứa 2 thành phần là SOAP Header và SOAP Body. SOA Header chứa các thông tin cần thiết cho việc thực hiện chuyển thông điệp hay cơ chế định danh, bảo mật. SOAP Body chứa dữ liệu ứng dụng. c) WSDL – Web Services Description Language WSDL (Web Services Description Language) là một dạng tài liệu dựa trên cú pháp XML để mô tả các dịch vụ Web. Lúc đầu nó đƣợc Microsoft, IBM và Ariba để xuất, nhƣng hiện nay đƣợc quản lý bởi tổ chức W3C. Một tài liệu WSDL sẽ cung cấp tài liệu cho các hệ thống phân tán nhƣ mô tả chức năng của một Web Services, cách thức tƣơng tác, các thông điệp tƣơng ứng cho các theo tác request hay response. Sau đây là cấu trúc cơ bản của một tài liệu. Một tài liệu WSDL bao gồm hai thành phần chính: Phần trừu tƣợng (abstract definitions) Error! Reference source not found và phần hiện thực (concrete definitions)Error! Reference source not found Phần trừu tƣợng bao gồm các thông tin đƣợc chứa các thẻ types, message, operation và port types. Phần hiện thực chứa thông tin trong các thẻ bindings và ports. Mỗi thành phần sẽ có một tham chiếu đến một thành phần khác đƣợc mô tả nhƣ hình sau: