Cộng đồng chia sẻ tri thức Lib24.vn

2. Các lớp SqlClient trong mô hình ADO.NET

Gửi bởi: Nguyễn Thị Thu Hiếu 18 tháng 2 2020 lúc 10:25:20


Mục lục
* * * * *

Danh sách sau chứa các classes ADO.NET mà chúng sẽ được sử dụng trong quá trình xây dựng ứng dụng sử dụng SQL Server Databases:

  1. SqlConnection
  2. SqlDataAdapter
  3. SqlCommand
  4. SqlParameter
  5. SqlDataReader

Chú ý: Chúng là các SqlClient cụ thể, trừ namespace OleDb có rất nhiều close tương đương. Mỗi khi ta muốn sử dụng lớp classes này, ta phải add một tham chiếu tới tên miền System.Data. Để đơn giản, ta có thể sử dụng từ khóa Imports, và lúc đó ta không cần phải điền đầy đủ các thành phần tên miền của SqlClient trong code, như đoạn code sau:

Imports System.Data.SqlClient

Nếu ta muốn sử dụng lõi của classes ADO.NET, như là DataSet và DataView không cần gõ đầy đủ tên miền, ta cần phải Import the tên miền System.Data, như đoạn code tiếp theo:

Imports System.Data

Ta nên quen thuộc với việc import các tên miền khác nhau trong project của ta. Tuy nhiên, để được toàn diện ta sẽ phủ chúng khi thực hành các bài tập. Bây giờ, ta xem xét các classes chính tồn tại trong namespace System.Data.SqlClient.

1. Class SqlConnection

Class SqlConnection có thể coi là “trái tim” của các classes mà ta sẽ thảo luận trong phần này, bởi vì nó cung cấp một connection tới SQL Server database.

Khi xây dựng một đối tượng SqlConnection, ta có thể chọn để chỉ định một chuỗi kết nối (connection strings) như một tham số. Chuỗi connection chứa tất cả các thông tin cần thiết để mở một connection tới your database.

Nếu ta không chỉ định chuỗi kết nối trong khi xây dựng, ta có thể thiết lập nó bằng việc sử dụng thuộc tính SqlConnection.ConnectionString.

  Ta xem xét các chuỗi connection strings làm việc như thế nào?  

* Các tham số của chuỗi kết nối (Connection String Parameters)

  Phương thức để chuỗi connection string được xây dựng sẽ phụ thộc vào data provider gì ta đang sử dụng. Khi truy xuất SQL Server, ta thường cung cấp Server và Database, được chỉ dẫn theo bảng sau:  

Ta cũng cần một vài thông tin về authentication và thực hiện theo hai cách: bằng cách cung cấp username và password trong chuỗi kết nối (connection strings) hoặc bằng cách kết nối tới SQL Server sử dụng NT account mà ứng dụng đang chạy trong đó.

Nếu ta muốn connect tới server bằng việc chỉ định username và password, ta cần tính đến các parameters đó trong chuỗi kết nối connection, được cho trong bảng sau:

Tuy nhiên, SQL Server có thể được thiết lập sử dụng Windows NT account của user người đang chạy chương trình để mở connection. Trong trường hợp này, ta không cần chỉ định username và password. Ta chỉ cần phải chỉ định nó khi ta đang sử dụng integrated security (security kết hợp - Phương thức này được gọi là security kết hợp bởi vì SQL Server đang được kết hợp với Windows NT’s security system và cung cấp connection an toàn nhất bởi vì các tham số User ID và Password parameters phải được chỉ định trong code). Ta sử dụng tham số Integrated Security này, và thiết lập là True khi ta muốn connect SQL Server đang sử dụng user’s NT account hiện tại. Tất nhiên, với các làm việc này, user của ứng dụng phải được cho phép sử dụng SQL Server database. Giả dụ như là đang sử dụng SQL Server Enterprise Manager.

Để hiểu chức năng của các tham số này trong chuỗi kết nối ta khởi tạo một đối tượng connection, xét đoạn code sau. Nó sử dụng lớp SqlConnection để khởi tạo một đối connection mà được sử dụng chỉ định user ID và password trong chuỗi kết nối:

Dim objConnection As New SqlConnection _ ("server=THUHUONG;database=QLDiemSV;" &_ "user id=sa;password=pass2008")

  Chuỗi kết nối này sẽ connects tới SQL Server database. Tham số Server chỉ định là database nằm trên máy THUHUONG. Tham số Database chỉ định database mà ta muốn truy cập, trong trường hợp này là database QLDiemSV. Cuối cùng, các tham số User ID và Password chỉ định User ID và password của user định nghĩa trên database. Ta thấy rằng, mỗi một tham số được gán một giá trị qua dấu =, và mỗi cặp parameter - value được phân cách nhau nhau bởi dấu chấm phảy. Hoặc:

Dim objConnection As SqlConnection = New _ SqlConnection(“Server=localhost;Database=pubs;” & _ “User ID=sa;Password=vbdotnet;”)

Chuỗi kết nối này sẽ connects tới SQL Server database. Tham số Server chỉ định là database nằm trên máy local. Tham số Database chỉ định database mà ta muốn truy cập là database pubs. Cuối cùng, các tham số User ID và Password chỉ định User ID và password của user định nghĩa trên database.  

* Mở và đóng Connection

Sau khi khởi tạo đối tượng connection với một chuỗi connection như đã trình bày ở phần trước, ta có thể gọi các phương thức của đối tượng SqlConnection như là Open và Close, thậm chí open và close một connection tới database được chỉ định trong chuỗi kết nối connection. Ví dụ, cho đoạn code sau:

Open the database connection objConnection.Open()
... Use the connection
Close the connection... objConnection.Close()

Chú ý: Ta có thể sử dụng trình Wizard để thực hiện kết nối với CSDL theo sự chỉ dẫn của nó.

2. Class SqlCommand

Lớp SqlCommand đại diện cho các câu lệnh SQL để thực hiện truy vấn dữ liệu lưu trữ. Các câu lệnh là truy vấn select, insert, update, hoặc delete,.v.v… Có thể là các chuỗi SQL hoặc gọi một stored procedure. Và truy vấn được thực hiện có thể chứa các tham số hoặc không chứa các tham số.

Kiến trúc của lớp SqlCommand có một vài biến số, nhưng phương thức đơn giản nhất để khởi tạo một đối tượng SqlCommand với không tham số (parameters). Tiếp theo, sau khi đối tượng đã được khởi tạo, ta có thể thiết lập các thuộc tính ta cần để thực hiện các thao tác sắp tới. Đoạn code sau cho phép khởi tạo một đối tượng SqlCommand:

Dim objCommand As SqlCommand = New SqlCommand()

  Khi sử dụng các data adapters (bộ điều hợp dữ liệu) và datasets, không cần gọi nhiều các đối tượng của chúng. Chúng có thể chủ yếu được sử dụng cho việc thực thi một câu lệnh select, delete, insert, hoặc update, mà đó là những gì ta đề cập trong chương này. Ta cũng có thể sử dụng các đối tượng command với data reader. Một data reader là một lựa chọn khác với DataSet mà nó sử dụng một vài tài nguyên hệ thống nhưng kém mềm dẻo.  

* Thuộc tính Connection

Một vài thuộc tính phải được thiết lập trên đối tượng SqlCommand trước khi ta có thể thực hiện một câu truy vấn. Thuộc tính đầu tiên trong các thuộc tính này đó là thuộc tính Connection. Thuộc tính này thiết lập tới đối tượng SqlConnection như trong đoạn code sau:

objCommand.Connection = objConnection

Chú ý: Để câu lệnh được thực hiện thành công, thì connection phải được mở ở thời điểm thực hiện.

* Thuộc tính CommandText

  Thuộc tính tiếp theo phải được thiết lập đó là thuộc tính CommandText. Thuộc tính này chỉ định chuỗi SQL hoặc stored procedure sẽ được thực hiện. Hầu hết các databases quy định đặt các các giá trị của chuỗi trong cặp dấu “ các giá trị của chuỗi “, ví dụ:  

Dim objConnection As New SqlConnection _

("server=THUHUONG;database=QLDiemSV;" &_ "user id=sa;password=pass2008")

Dim objCommand As SqlCommand = New SqlCommand() ' Open the connection, execute the command objConnection.Open()

objCommand.Connection = objConnection objCommand.CommandText = "INSERT INTO HOSOSV " & _

"(MaSV, HoDem, TenSV, NgaySinh, MaLop) " & _ "VALUES(‘SV001’,’Nguyen Thi’,’Hoa’,’12/8/1988’,’TH05’)"

' Set the SqlCommand object properties...

Câu lệnh INSERT chỉ đơn giản nghĩa là “chèn một hàng mớí vào bảng HOSOSV. Trong đó cột MaSV nhận giá trị ‘SV001’, HoDem nhận giá trị ’Nguyen Thi’, TenSV nhận giá trị ’Hoa’, NgaySinh nhận giá trị ’12/8/1988’ và cột MaLop nhận giá trị ’ TH05’.”

Với cách cơ bản này các câu lệnh INSERT làm việc trong SQL. Ta có, theo sau INSERT INTO là tên của bảng. Tiếp là một danh sách tên các cột trong cặp dấu ngoặc đơn. Tiếp theo nữa là từ khóa VALUES là danh sách các giá trị được chèn vào cột theo đúng thứ tự.

Trong ví dụ trên, với các giả thiết là ta biết các giá trị để chèn trong khi thực hiện chương trình, thường là không có thực trên hầu hết các ứng dụng. Cũng may, ta cũng có thể tạo các câu lệnh với các tham số và thiết lập giá trị cho các tham số đó một cách độc lập. Ta sẽ tìm hiểu cách sử dụng các tham số đó như thế nào trong phần Parameters Collection.

* Parameters Collection

Placeholders, ký hiệu @, là tiền tố các biến trong các câu lệnh SQL; Chúng được điền vào trước các tham số. Như vậy, nếu ta muốn cập nhật bảng HOSOSV được mô tả trong ví dụ trước nhưng không biết các giá trị tại thời điểm thiết kế, ta chỉ cần viết:

Dim objConnection As New SqlConnection _

("server=THUHUONG;database=QLDiemSV;" &_ "user id=sa;password=pass2008")

Dim objCommand As SqlCommand = New SqlCommand() ' Open the connection, execute the command objConnection.Open()

objCommand.Connection = objConnection objCommand.CommandText = "INSERT INTO HOSOSV " & _

"(MaSV, HoDem, TenSV, NgaySinh, MaLop) " & _ "VALUES(@MaSV,@Hodem,@TenSV,@NgaySinh,@MaLop)"

' Set the SqlCommand object properties...

Ở đây, thay vì cung cấp các giá trị cụ thể, ta cung cấp các placeholders. Placeholders, như đã đề cập, luôn xuất hiện với ký hiệu @. Chúng không cần được đặt trước tên các trường trong các bảng của database mà chúng thể hiện, nhưng thường đơn giản hơn nếu ta sử dụng tên tham số trùng với tên trường dữ liệu, vì nó thường tốt hơn cho chính các văn bản code của ta.

Tiếp theo, ta cần tạo các tham số mà sẽ được sử dụng để truyền giá trị cho các placeholders khi câu lệnh SQL được thực hiện. Ta cần phải create và add các tham số vào Parameters collection của đối tượng SqlCommand.

Thuật ngữ parameters chỉ các tham số cần thiết cho câu lệnh SQL hoặc stored procedure, không chỉ các tham số được quy định chuyển để chuyển sang các phương thức của Visual Basic 2005.

Ta có thể truy cập vào tập Parameters collection của đối tượng SqlCommand bằng việc chỉ định thuộc tính Parameters. Sau khi truy cập vào tập Parameters collection, ta có thể sử dụng các thuộc tính và các phương thức của nó để tạo một hoặc nhiều hơn các tham số trong collection. Cách tốt nhất để add một tham số tới câu lệnh được mô tả trong ví dụ sau:

Dim objConnection As New SqlConnection _

("server=THUHUONG;database=QLDiemSV;" &_ "user id=sa;password=pass2008")

Dim objCommand As SqlCommand = New SqlCommand() ' Open the connection, execute the command objConnection.Open()

Set the SqlCommand object properties... objCommand.Connection = objConnection objCommand.CommandText = "INSERT INTO HOSOSV " & _

"(MaSV, HoDem, TenSV, NgaySinh, MaLop) " & _ "VALUES(@MaSV,@Hodem,@TenSV,@NgaySinh,@MaLop)"

Add parameters for the placeholders in the SQL in the

objCommand.Parameters.AddWithValue("@MaSV", txtMaSV.Text) objCommand.Parameters.AddWithValue("@Hodem", txtHodem.Text) objCommand.Parameters.AddWithValue("@TenSV", txtTenSV.Text) objCommand.Parameters.AddWithValue("@NgaySinh",_

txtNgaySinh.Text).DbType = DbType.Date objCommand.Parameters.AddWithValue("@MaLop", cboMaLop.Text)

  Phương thức AddWithValue thừa nhận tên của tham số và đối tượng ta muốn add. Trong trường hợp này, ta sử dụng thuộc tính Text của đối tượng Text box trên cùng một Form.  

* Phương thức ExecuteNonQuery

Cuối cùng, ta có thể thực hiện các câu lệnh. Để làm điều này, connection cần phải được mở. Ta có thể gọi phương thức ExecuteNonQuery của đối tượng SqlCommand. Phương thức này thực hiện câu lệnh SQL và là nguyên

nhân dữ liệu được chèn vào database. Để hoàn thành đoạn code, ta phải mở connection, thực hiện query, và đóng connection trở lại:

Dim objConnection As New SqlConnection _

("server=THUHUONG;database=QLDiemSV;" &_ "user id=sa;password=pass2008")

Dim objCommand As SqlCommand = New SqlCommand() ' Set the SqlCommand object properties... objCommand.Connection = objConnection

objCommand.CommandText = "INSERT INTO HOSOSV " & _ "(MaSV, HoDem, TenSV, NgaySinh, MaLop) " & _ "VALUES(@MaSV,@Hodem,@TenSV,@NgaySinh,@MaLop)"

Add parameters for the placeholders in the SQL in the



objCommand.Parameters.AddWithValue("@MaSV", txtMaSV.Text) objCommand.Parameters.AddWithValue("@Hodem", txtHodem.Text) objCommand.Parameters.AddWithValue("@TenSV", txtTenSV.Text) objCommand.Parameters.AddWithValue("@NgaySinh",_

txtNgaySinh.Text).DbType = DbType.Date objCommand.Parameters.AddWithValue("@MaLop", cboMaLop.Text)

Open the connection, execute the command objConnection.Open()

Try

objCommand.ExecuteNonQuery() Catch SqlExceptionErr As SqlException

MessageBox.Show(SqlExceptionErr.Message) End Try

Execute the SqlCommand object to insert the new data...

Close the connection... objConnection.Close()

* Phương thức ExecuteReader

Trái với phương thức ExecuteNonQuery, phương thức ExecuteReader của đối tượng SqlCommand sẽ thực hiện truy vấn trả về kết quả trên đối tượng DataReader. Và dữ liệu trên DataReader thường được đổ sang các điều khiển ListBox, ComboBox trên form ứng dụng.

Dim objCommand As SqlCommand = New SqlCommand() Dim objDataReader As SqlDataReader

Declare local variables and objects...

Open the connection, execute the command objConnection.Open()

Set the SqlCommand object properties... objCommand.Connection = objConnection

objCommand.CommandText = "Select MaLop, TenLop From Lop"
Execute the SqlCommand object to insert the new data... objDataReader = objCommand.ExecuteReader cboMaLop.Items.Clear()

Do While (objDataReader.Read()) cboMaLop.Items.Add(objDataReader.Item(0))

Loop

Close the connection...

objConnection.Close()

3. Class SqlDataAdapter

Lớp SqlDataAdapter tương tự như lớp OleDbDataAdapter. Điểm khác nhau chính là OleDbDataAdapter có thể truy cập vào bất cứ data source được supports OLE DB, trong khi SqlDataAdapter chỉ supports cho SQL Server databases. Ta có thể sử dụng trong cùng một cách như nhau; ta có thể cấu hình SqlDataAdapter sử dụng wizards, giống như là cấu hình cho OleDbDataAdapter (được cung để ta đang truy xuất vào SQL Server data source), ta sẽ trình bày trong ví dụ minh họa cụ thể ở phần sau. Trong phần này, ta tìm hiểu cách cấu hình và sử dụng SqlDataAdapter trong code, những nguyên tắc này cũng có thể áp dụng cho OleDbDataAdapter.

Data adapters hoạt động như một cầu nối giữa data source và các đối tượng lưu dữ liệu trong bộ nhớ, như là DataSet. Để truy xuất data source, chúng sử dụng các đối tượng command, ta đã xem xét ở trên. Các đối tượng command này liên quan đến các connections, vì vậy data adapter này dựa vào các đối tượng command và connection để truy xuất và điều khiển data source.

Thuộc tính SelectCommand của lớp SqlDataAdapter được sử dụng nắm giữ một SqlCommand để gọi dữ liệu từ data source. Sau đó data adapter đẩy kết quả của truy vấn vào DataSet hoặc DataTable.

SqlDataAdapter cũng có các thuộc tính UpdateCommand, DeleteCommand, and InsertCommand. Chúng cũng là các đối tượng SqlCommand, được sử dụng để ghi các thay đổi với DataSet hoặc DataTable quay trở lại data source. Vấn đề này có thể thấy phức tạp, nhưng các tools thực tế rất dễ sử dụng. Ta đã học các câu lệnh SQL trong chương trước để viết

SelectCommand, và các tools được gọi command builders mà ta có thể tạo một cách tự động các câu lệnh khác dựa trên chúng.

Xét thuộc tính SelectCommand và xét xem ta có thể tạo các câu lệnh cho việc updating, deleting, và inserting records như thế nào.

* Thuộc tính SelectCommand

Thuộc tính SelectCommand của lớp SqlDataAdapter được dùng để đẩy dữ liệu vào từ SQL Server database DataSet, như hình vẽ Hình 5.4.

Hình 5.4. Thuộc tính Select Command

Khi ta muốn đọc dữ liệu từ kho dữ liệu, đầu tiên ta phải thiết lập thuộc tính SelectCommand của lớp SqlDataAdapter. Thuộc tính này là đối tượng SqlCommand và nó được dùng để chỉ định dữ liệu được select và select dữ liệu như thế nào. Vì vậy, thuộc tính SelectCommand cũng có các thuộc tính của nó, và ta cần thiết lập chúng như là thiết lập các thuộc tính trên các câu lệnh thông thường. Ta đã xem xét các thuộc tính sau của đối tượng SqlCommand:

  1. Connection: Thiết lập đối tượng SqlConnection để truy xuất vào data store.
  2. CommandText: Thiết lập các câu lệnh SQL hoặc tên stored procedure được sử dụng để select dữ liệu.

Trong các ví dụ trước của các đối tượng SqlCommand, ta đã sử dụng trực tiếp các câu lệnh SQL. Nếu ta muốn sử dụng các stored procedures, ta cần phải sử dụng thêm thuộc tính CommandType, thuộc tính này thiết lập một giá trị xác định xem thuộc tính CommandText được biên dịch như thế nào.

Trong chương này, ta tập trung vào các câu lệnh SQL, nhưng các stored procedures thường cũng rất hữu dụng, đặc biệt là nếu chúng đã tồn tại trên database. Nếu ta muốn sử dụng chúng, thì thiết lập thuộc tính CommandText với tên của stored procedure (chú ý là phải được đóng trong cặp dấu ngoặc kép “tên của stored procedure hoặc chuỗi SQL “ bởi trình trình biên dịch biên dịch chúng như là một string), và thiết lập thuộc tính CommandType thành CommandType.StoredProcedure.

* Thiết lập SelectCommand với một chuỗi SQL

Xét xem làm thế nào, ta có thể thiết lập các thuộc tính trên trong code. Đoạn code sau cho ta thấy các cách thiết lập điển hình khi thực hiện chuỗi SQL string:

‘ Declare a SqlDataAdapter object...

Dim objDataAdapter As New SqlDataAdapter()

‘ Assign a new SqlCommand to the SelectCommand property objDataAdapter.SelectCommand = New SqlCommand()

‘ Set the SelectCommand properties...

objDataAdapter.SelectCommand.Connection = objConnection objDataAdapter.SelectCommand.CommandText = _

“SELECT MaSV, HoDem, TenSV, FROM HOSOSV ORDER BY TenSV,

Hodem”

Đầu tiên trong đoạn code trên khai báo đối tượng SqlDataAdapter. Đối tượng này có thuộc tính SelectCommand được thiết lập bằng SqlCommand; Ta chỉ cần thiết lập các thuộc tính của command. Ta thiết lập các thuộc tính bằng việc thiết lập thuộc tính Connection, để đối tượng connection được hợp lệ thì nó phải được tạo trước đoạn code trên. Tiếp theo, ta thiết lập các thuộc tính của thuộc tính CommandText bằng các câu lệnh SQL SELECT.

Thiết lập SelectCommand với một Stored Procedure

Trong đoạn code tiếp theo, ta tìm hiểu cách thiết lập các thuộc tính trên khi sử dụng để thực hiện một stored procedure. Một stored procedure là một nhóm các câu lệnh SQL và đã được lưu trữ trong database dưới một tên duy nhất và được thực hiện như một unit. stored procedure trong ví dụ này (usp_select_DSSV) sử dụng cùng câu lệnh SQL ta đã sử dụng trong phần trước:

‘ Declare a SqlDataAdapter object...

Dim objDataAdapter As New SqlDataAdapter()

‘ Assign a new SqlCommand to the SelectCommand property objDataAdapter.SelectCommand = New SqlCommand()

objDataAdapter.SelectCommand.Connection = objConnection objDataAdapter.SelectCommand.CommandText = “usp_select_DSSV” objDataAdapter.SelectCommand.CommandType = CommandType.StoredProcedure

‘ Set the SelectCommand properties...

Thuộc tính CommandText bây giờ được chỉ định bằng tên của stored procedure mà ta muốn thực hiện thay vì chuỗi SQL đã được chỉ định trong ví dụ trước. Cũng phải chú ý đến thuộc tính CommandType. Trong ví dụ trước ta không cần phải chuyển đổi thuộc tính này, bởi vì nó được mặc định là CommandType.Text, mà ta cần thiết lập để thực hiện các câu lệnh SQL. Trong ví dụ này, ta phải thiết lập giá trị CommandType.StoredProcedure, để chỉ dẫn rằngthuộc tính CommandText chứa tên của stored procedure để thực hiện.

Sử dụng Command Builders để tạo các Commands khác

SelectCommand là tất cả những gì ta cần thiết để chuyển dữ liệu từ database vào DataSet. Sau khi ta cho phép các users thay đổi đối với DataSet, ta muốn ghi những thay đổi đó trở lại database. Ta có thể làm điều này bằng việc điều chỉnh các đối tượng câu lệnh SQL cho các công việc inserting, deleting, and updating. Một lựa chọn khác, ta có thể sử dụng các stored procedures. Cả hai giải pháp phụ thuộc vào sự am hiểu về SQL. Rất may là, có một cách đơn giản hơn, ta có thể sử dụng command builders để tạo các câu lệnh này. Nó chỉ có một dòng trong các dòng sau:

‘ Declare a SqlDataAdapter object...

Dim objDataAdapter As New SqlDataAdapter()

‘ Assign a new SqlCommand to the SelectCommand property objDataAdapter.SelectCommand = New SqlCommand()

‘ Set the SelectCommand properties... objDataAdapter.SelectCommand.Connection = objConnection objDataAdapter.SelectCommand.CommandText = “usp_select_DSSV” objDataAdapter.SelectCommand.CommandType = CommandType.StoredProcedure

‘ automatically create update/delete/insert commands Dim objCommandBuilder As SqlCommandBuilder = New _ SqlCommandBuilder(objDataAdapter)

Như vậy, ta có thể sử dụng SqlDataAdapter để ghi những thay đổi dữ liệu trở lại database. Ta tìm hiểu kỹ hơn về vấn đề này trong phần ví dụ minh họa. Để hiểu, ta xét các phương thức mà lấy dữ liệu từ database đẩy vào DataSet:Phương thức Fill .

* Phương thức Fill

Ta dùng phương thức Fill để dữ liệu đẩy dữ liệu mà đối tượng SqlDataAdapter sử dụng SelectCommand của nó lấy từ kho lưu trữ dữ liệu vào đối tượng DataSet. Tuy nhiên, trước khi làm điều đó, ta phải khởi tạo đối tượng DataSet. Để sử dụng đối tượng DataSet trong project của ta, ta phải add một tham chiếu tới System.Xml.

‘ Declare a SqlDataAdapter object...

Dim objDataAdapter As New SqlDataAdapter()

‘ Assign a new SqlCommand to the SelectCommand property objDataAdapter.SelectCommand = New SqlCommand()

‘ Set the SelectCommand properties... objDataAdapter.SelectCommand.Connection = objConnection objDataAdapter.SelectCommand.CommandText = “usp_select_DSSV” objDataAdapter.SelectCommand.CommandType = CommandType.StoredProcedure

Dim objDataSet as DataSet = New DataSet()

Ta có hai đối tượng DataSet và SqlDataAdapter, có thể điền dữ liệu vào DataSet. Phương thức Fill có nhiều phiên bản, nhưng ta sẽ chỉ xét thảo luận một phiên bản hay được sử dụng nhiều nhất. Cú pháp của phương thức Fill được cho như sau:

SqlDataAdapter.Fill(DataSet, string)

  Đối số DataSet chỉ định một đối tượng DataSet hợp lệ mà dữ liệu được lưu trữ ở trong đó. Đối số string gán với tên mà ta muốn bảng có trong DataSet. Chú ý rằng, một DataSet có thể chứa nhiều bảng. Ta có thể sử dụng bất cứ tên nào ta muốn, nhưng thường tốt nhất là sử dụng tên của các bảng nơi mà dữ liệu trong database đến. Nó giúp cho văn bản code của ta và làm cho code dễ bảo trì.  

Đoạn code sau gọi phương thức Fill. Chuỗi “authors” được chỉ định là đối số string. Nó là tên ta muốn sử dụng khi đang thao tác trong các phiên bản nhớ của bảng này; nó cũng là tên của bảng trong data source.

‘ Declare a SqlDataAdapter object...

Dim objDataAdapter As New SqlDataAdapter()

‘Create an instance of a new select command object objDataAdapter.SelectCommand = New SqlCommand()

‘ Set the SelectCommand properties... objDataAdapter.SelectCommand.Connection = objConnection objDataAdapter.SelectCommand.CommandText = “usp_select_DSSV” objDataAdapter.SelectCommand.CommandType = CommandType.StoredProcedure

Dim objDataSet as DataSet = New DataSet()

‘ Fill the DataSet object with data... objDataAdapter.Fill(objDataSet, “DSSV”)

Phương thức Fill sử dụng thuộc tính SelectCommand.Connection để connect tới database. Nếu connection đã được mở, data adapter sẽ sử dụng nó để thực hiện SelectCommand. Và nếu như connection đã đóng thì data adapter sẽ mở nó, thực hiện SelectCommand, và sau đó đóng trở trở lại. Bây giờ ta đã có dữ liệu trong bộ nhớ, và có thể bắt đầu thao tác nó không phụ thuộc vào data source.

Chú ý: Lớp DataSet không có Sql tại vị trí bắt dầu tên lớp của nó. Bởi vì DataSet không nằm trong namespace System.Data.SqlClient, nó nằm trong lớp cha namespace System.Data. Các lớp trong tên miền này có liên quan căn bản với thao các dữ liệu trong bộ nhớ.

Một lần nữa, ta đã có dữ liệu được load vào DataSet, tính chất quan trọng của data source không còn nữa (trừ khi ta muốn ghi trở lại). Ta hãy xét hai trong các lớp trong namespace: DataSet và DataView.

4. Class DataSet

Lớp DataSet được dùng để lưu trữ dữ liệu được lấy từ một kho dữ liệu và lưu trữ dữ liệu trong bộ nhớ trên client. Đối tượng DataSet chứa một tập các tables, relationships, và các ràng buộc constraints thích hợp với dữ liệu đọc từ kho dữ liệu. Nó hoạt động như một bộ máy database gọn nhẹ, cho phép ta lưu trữ tables, edit data, và chạy các truy vấn dựa vào việc sử dụng đối tượng DataView.

Dữ liệu trong DataSet không được connect từ kho dữ liệu, và ta có thể làm việc với dữ liệu độc lập với kho dữ liệu. Ta có thể thao tác dữ liệu trong đối tượng DataSet bằng việc adding, updating, và deleting the records. Ta có thể áp các thay đổi này quay trở lại kho dữ liệu gốc sau khi sử dụng data adapter.

Dữ liệu trong đối tượng DataSet được duy trì trong Extensible Markup Language (XML), nghĩa là ta có thể save DataSet như là một file hoặc đơn giản chuyển nó trên network. XML được bảo vệ từ ta, những người phát triển, và chúng ta không bao giờ nên edit trực tiếp XML. Tất cả các thao tác editing XML được thực hiện thông qua các thuộc tính và các phương thức của lớp DataSet. Nhiều nhà phát triển thích sử dụng XML và lựa chọn để thao tác XML biểu diễn trực tiếp DataSet, nhưng điều này không cần thiết.

Giống như bất cứ bản document XML nào, DataSet có một schema (một file cấu trúc của dữ liệu trên một hoặc nhiều XML files). Khi ta sinh ra một kiểu dataset dùng wizard, XML Schema Definition (XSD) file được add vào Solution Explorer, như hình 5.6.

Hình 5.6. File XML Schema Definition

File này là một XML schema cho dữ liệu QLDiemSVDataSet chứa nó. Từ đây, Visual Studio .NET tạo ra một lớp kế thừa từ DataSet và sử dụng schema cụ thể này. Một lược đồ DataSet chứa các thông tin về tables, relationships, and constraints được lưu trữ trong DataSet. Thêm nữa, nó được bảo vệ từ phía ta, và ta không cần biết XML làm việc với DataSet.

5. DataView

Lớp DataView được sử dụng tiêu biểu cho việc sorting, filtering, searching, editing, và navigating dữ liệu từ DataSet. Một DataView là bindable, nghĩa là nó có thể bị buộc vào các điều khiển giống như cách DataSet bị buộc vào các điều khiển. Hơn nữa, ta sẽ tìm hiểu nhiều hơn về cách buộc dữ liệu trong code trong phần tiếp theo của chương.

Một DataSet có thể chứa một số các đối tượng DataTable; khi ta sử dụng phương thức Fill của lớp SqlDataAdapter để add dữ liệu vào DataSet, như vậy ta đã thực sự đang tạo một đối tượng DataTable bên trong DataSet này. DataView cung cấp view thông dụng của DataTable; ta có thể sắp xếp và lọc dữ liệu, như ta thực hiện trên truy vấn SQL.

Ta có thể tạo một DataView từ dữ liệu được chứa trong DataTable mà đang chỉ chứa dữ liệu mà ta muốn hiển thị. Ví dụ, nếu dữ liệu trong DataTable chứa tất cả các Sinh viên được sắp xếp bởi Tên và Họ đệm, ta có thể tạo một DataView chứa tất cả Sinh viên được sắp xếp bởi Tên và sau đó là Họ đệm. Hoặc, nếu muốn, ta có thể tạo một DataView chỉ chứa một vài sinh viên chứa tên nào đó.

Mặc dù ta có thể view dữ liệu trong DataView trong nhiều cách khác nhau từ DataTable cơ bản, nó vẫn là cùng dữ liệu. Các thay đổi với DataView ảnh hưởng tới DataTable cơ bản một cách tự động và các thay đổi với DataTable cơ bản tự động ảnh hưởng bất kỳ đối tượng DataView mà đang hiển thị DataTable đó.

Kiến trúc cho lớp DataView khởi tạo một thể hiện mới của lớp DataView và lấy DataTable là một đối số. Đoạn code sau khai báo một đối tượng DataView và khởi tạo nó đang sử dụng bảng HosoSV từ DataSet có tên là objDataSet. Chú ý rằng code đó truy cập vào tập hợp Tables của đối tượng DataSet, bằng việc chỉ định thuộctính Tables và tên bảng:

‘ Set the DataView object to the DataSet object...

Dim objDataView = New DataView(objDataSet.Tables(“HosoSV”))

* Thuộc tính Sort

  Khi DataView đã được khởi tạo và hiển thị dữ liệu, ta có thể thay đổi view của dữ liệu đó. Ví dụ, giả sử ta muốn sắp xếp dữ liệu khác với thứ tự trong DataSet. Để sắp xếp dữ liệu trong DataView, ta thiết lập thuộc tính Sort và chỉ định cột hoặc các cột mà ta muốn sắp xếp. Đoạn code sau sẽ sắp xếp dữ liệu trong DataView theo Tên và sau đó theo Họ đệm của danh sách Sinh viên:  

objDataView.Sort = “TenSV, Hodem”

Chú ý: Thuộc tính Sort giống như cú pháp của mệnh đề ORDER BY trong câu lệnh SQL. Như trong SQL mệnh đề ORDER BY, thao tác sắp xếp trên DataView thường sắp xếp theo thứ tự mặc định là tăng dần. Nếu ta muốn thay đổi theo thứ tự sắp xếp giảm, ta cần phải có chỉ định từ khóa DESC:

objDataView.Sort = “TenSV, Hodem DESC”

* Thuộc tính RowFilter

Khi đã khởi tạo DataView, ta có thể lọc các dòng dữ liệu mà chúng sẽ chứa. Nó tương tự như chỉ định trong mệnh đề WHERE của câu lệnh SQL SELECT; chỉ những hàng thỏa mãn điều kiện sẽ được giữ lại trên view. Dữ liệu cơ bản không bị ảnh hưởng. Thuộc tính RowFilter chỉ định một điều kiện lọc mà có thể áp dụng được trên DataView. Cú pháp này cũng tương tự như mệnh đề SQL WHERE. Nó chứa ít nhất tên một cột, theo sau là một toán tử và giá trị. Nếu giá trị là string thì nó phải được bao trong cặp dấu ‘nháy đơn’, ví dụ ta có đoạn code sau:

objDataView = New DataView(objDataSet.Tables(“HosoSV”)) objDataView.RowFilter = “TenSV = ‘Hoa’”
‘ Set the DataView object to the DataSet object...

Nếu bạn muốn lấy lại các ròng trừ các dòng có Tên là =’Hoa’

‘ Set the DataView object to the DataSet object... objDataView = New DataView(objDataSet.Tables(“authors”))
objDataView.RowFilter = “TenSV <> ‘Hoa’”

Ta cũng có thể chỉ định điều kiện lọc phức tạp hơn như trong SQL. Ví dụ, sử dụng toán tử AND:

objDataView.RowFilter = “TenSV <> ‘Hoa’ AND Hodem LIKE ‘N*’”

* Phương thức Find

Nếu ta muốn tìm kiếm cho một hàng dữ liệu trong DataView, ta gọi phương thức Find. Phương thức Find tìm kiếm dữ liệu trong cột khóa sắp xếp của DataView. Do đó, trước khi gọi phương thức Find, ta trước hết hãy sắp xếp DataView trên cột chứa dữ liệu mà ta muốn tìm kiếm. Cột trong DataView đã được sắp xếp trở thành cột khóa sắp xếp trong đối tượng DataView object.

Ví dụ, giả sử ta muốn tìm kiếm Sinh viên có TenSV là ‘Anh’. Ta cần sắp xếp dữ liệu trong DataView theo TenSV và thiết lập cột này thành cột khóa sắp xếp trong DataView, và sau đó gọi phương thức Find, như đoạn code sau:

Dim intPosition as Integer objDataView.Sort = “TenSV” intPosition = objDataView.Find(“Ann”)

Phương thức Find tìm kiếm và trả về vị trí của bản ghi trong DataView. Trong trường hợp ngược lại, DataView trả về giá trị null nếu không tìm thấy. Nếu phương thức Find tìm thấy một bản khớp thì nó sẽ dừng tìm kiếm và trả về vị trí của bản ghi đầu tiên tìm thấy. Nếu ta muốn có nhiều hơn một bản ghi trong data store, ta phải lọc dữ liệu trong DataView, dữ liệu của ta sẽ được hiển thị.

Phương thức Find không phân biệt dạng chữ, nghĩa là khi tìm Sinh viên có tên là ‘Hoa’, ta có thể nhập là ‘hoa’.

Phương thức Find tìm chính xác từng cụm từ, nghĩa là ta phải nhập toàn bộ cụm từ đó. Ví dụ, giả sử ta muốn tìm kiếm Sinh viên có Họ đệm là ‘Đinh Thanh’ thì ta phải nhập đầy đủ cụm đó.

objDataView.Sort = “Hodem”
intPosition = objDataView.Find(“Đinh Thanh”)

Ta thấy DataView có thể được sắp xếp trên nhiều hơn một cột tại cùng một thời điểm. Nếu ta muốn sắp xếp nhiều hơn một cột, ta cần cung cấp một mảng các giá trị để phương thức Find thay cho chỉ một giá trị đơn. Ví dụ, ta muốn tìm kiếm ‘Đinh Thanh Hoa’ xuất hiện trong DataView:

Dim intPosition As Integer Dim arrValues(1) As Object

objDataView.Sort = “Hodem, TenSV”

‘ Find the author named “Đinh Thanh Hoa”. arrValues(0)= “Đinh Thanh”

arrValues(1) = “Hoa”

intPosition = objDataView.Find(arrValues)

Được cập nhật: 20 giờ trước (13:14:22) | Lượt xem: 1928

Các bài học liên quan