Tuesday, May 17, 2011

Tìm hiểu DataAdapter, DataSet



Tìm hiểu về ObjectModel
Đầu tiên thì mình đưa ra một số so sánh giữa DataSet và DataReader nhé, để các bạn tránh hay hỏi nhiều về việc : Lúc nào thì xài DataSet và lúc nào thì xài DataReader, giống và khác nhau như thế nào ?
So sánh DataSet và DataReader
Nếu bạn đơn giản chi muốn lấy dữ liệu và trình bày nó ra thôi thì dùng DataReader. Đặc biệt trường hợp mà bạn đọc với một số lượng lớn dữ liệu, ví như là vòng lặp tới hàng triệu dòng kết quả dữ liệu, bạn muốn tốc độ đọc nhanh và trình bày nhanh thì DataReader được sử dụng cho mục đích này, NHANH và TIỆN LỢI, cho việc ĐỌC dữ liệu.
Nếu bạn muốn chỉnh sử dữ liệu rồi update thông tin dữ liệu lại database thì bạn sử dụng DataSet. DataAdapter lấp đầy (fill) dữ liệu vào DataSet bằng cách sử dụng một DataReader, thêm vào đó resource cần được lưu trữ vào để sử dụng khi ngắt kết nối. Vì vậy việc sử dụng DataSet tốn nhiều tài nguyên hơn DataReader rất nhiều, bạn cần cân nhắc ở đây lúc nào sử dụng thành phần nào thì tốt, tránh lạm dụng quá. Nếu như bạn muốn đọc dữ liệu và viết ra dưới dạng XML, hoặc export database schema, viết lại db dưới dạng XML,…. thì nên sử dụng DataReader.
Giới thiệu sơ qua về DataSet
DataSet trong ADO.NET là một bước phát triển lớn trong việc phát triển ứng dụng cơ sở dữ liệu đa hệ. Khi lấy và chỉnh sửa dữ liệu, duy trì liên tục kết nối tới Data Source trong khi chờ user yêu cầu thì rõ ràng là tốn tài nguyên máy rất nhiều.
DataSet giúp ích ở đây rất lớn. Vì DataSet cho phép lưu trữ dữ liệu và chỉnh sửa tại ‘local cache’, hay gọi là offline mode. Có thể xem xét và xử lý thông tin trong khi ngắt kết nối. Sau khi chỉnh sửa và xem xong thì tạo một kết nối và update dữ liệu từ local vào Data Source.
Dữ liệu trong DataSet được lưu trữ dưới dạng một Collection các Tables và bạn cần phải xử lý thông qua các lớp DataTable -> DataRow và DataColumn.
Bảng dưới đây là kiến trúc DataSet.
Bạn chỉ cần tưởng tượng rằng : bạn có một cái bể nước (DataSource) , một cái máy bơm (DataAdapter) và một cái thùng đựng nước (DataSet). Thì khi lấy nước dùng cái bơm lấy nước từ bể, kiểm tra và lọc nước sau đó lại dùng cái bơm hút lại về cái bể nước. Đó chính là vai trò của cái bơm và DataAdapter tương tự như vậy.
Tương quan 3 lớp như thế này :
Có 4 cách tạo DataAdapter :
1// Cách 1 : Đơn giản chỉ khai báo tạo đối tượng Adapter
2SqlDataAdapter da = new SqlDataAdapter();
3//  Cách 2 : Thiết lập đối tượng SqlCommand
4SqlDataAdapter da = new SqlDataAdapter(cmd);
5// Cách 3 : Thiết lập query và đối tượng SqlConnection
6SqlDataAdapter da = new SqlDataAdapter(sql, conn);
7// Cách 4 : Thiết lập query và mệnh lệnh thực thi
8SqlDataAdapter da = new SqlDataAdapter(sql, connString);

Giới thiệu về DataTable và thành phần kèm
Nằm trong lớp : System.Data.DataTable. Có cấu trúc theo cấu trúc của bảng trong cơ sở dữ liệu gồm các hàng và cột nên có 2 thành phần kèm theo là : DataRow và DataColumn
DataRow sẽ là tập hợp các cột (record-set)
DataColumn là tập hợp các hàng cùng một đặc tính. (Field)
1DataTable dt =  new DataTable();
2DataColumn col = dt.Columns[“Contact”]; // Cột Contact
3DataColumn col = dt.Columns[2];
4DataRow row = dt.Rows[2];
Làm việc với DataSet và DataAdapter
Tạo một dataset :
1<span style="font-size:100%;">
2DataSet ds = new DataSet();
3DataSet ds = new DataSet(“DataSet Name”);
4</span>


Nếu bạn dùng cách 1 thì theo mặc định DataSet sẽ có tên là “NewDataSet”, cách thứ 2 là bạn đặt tên luôn cho DataSet bên trong constructor. Hoặc bạn có thẻ thay đổi tên của DataSet bằng thuộc tính ‘DataSetName’
Có nhiều cách xử lý với DataSet như:
· + Sử dụng thông qua Adapter
· + Đọc từ một tài liệu XML
Thử xử lý dữ liệu bằng một ví dụ :
01using System;
02using System.Data;
03using System.Data.SqlClient;
04
05namespace MSSQL_Server
06{
07  class Database
08  {
09      static void Main(string[] args)
10      {
11          // Tạo connection strin
12          string connString = @"Server = NguyenVanThanh
13                                Integrated Security = True;
14                                Database = Demo
15          // Tạo SQL query
16          string sql = @"SELECT MaSV,TenSV FROM SinhVien";
17          // Tạo connection
18          SqlConnection conn = new SqlConnection(connString);
19          try
20          {
21              // Mỏ kết nối
22              conn.Open();
23              // Tạo Adapter
24              SqlDataAdapter da = new SqlDataAdapter(sql, conn);
25              // Tạo DataSet
26              DataSet ds = new DataSet();
27              // Lấp đầy kết quả vào DataSet
28              da.Fill(ds, "sinhvien");
29              // Tạo DataTable thu kết quả từ bảng
30              DataTable dt = ds.Tables["sinhvien"];
31              // In kết quả ra Console
32              foreach (DataRow row in dt.Rows)
33              {
34                  foreach (DataColumn col in dt.Columns)
35                      Console.WriteLine(row[col]);
36                  Console.WriteLine("".PadLeft(20, '='));
37              }
38          }
39          catch (Exception e)
40          {
41              // Bắt lỗi
42              Console.WriteLine(e.Message);
43          }
44          finally
45          {
46              // Đóng kết nối
47              conn.Close();
48          }
49      }
50  }
51}

Phân tích bài đơn giản ở trên nha.
Sau khi đã mở kết nối thì ta tạo một Adapter. Adapter này chứa thông tin về SQL query cần thực thi và một đối tượng kết nối conn, sau đó tạo một DataSet. Lúc này thì DataSet chưa có gì. Sau đó lấp đầy kết quả vào DataSet bằng method ‘Fill’ của Adapter. Từ đó hiểu thêm rằng : Adapter tự động thực thi câu lệnh SQL , thu lấy kết quả và gán hết vào DataSet. Khác với DataReader cần có một đối tượng SqlComnmand đễ xử lý. Nếu khi lấp đầy kết quả vào DataSet mà không gán tên bảng nào thì tự động trong DataSet tên lần lượt từng bảng là ‘TableN’ với bảng đầu tiên là Table, Table1,Table2…TableN.
Nếu một query được thực thi lại nhiều lần thì DataSet sẽ cập nhật thông tin từng đó bảng vào trong .
Chú ý trong Adapter ở trên nếu thay bằng cách tạo Adapter dưới đây :
1SqlDataAdapter da = new SqlDataAdapter();
2da.SelectCommand = new SqlCommand(sql, conn);

Thì kết quả thu được giống hệt nhau, không có gì thay đổi.
DataSet có thể chứa nhiều table vì thế khi xử lý Table nào cần phải gán vào DataTable một tên table cụ thể. Và cuối cùng dùng DataColumn và DataRow để xử lý DataTable đó. Đó là cách extract dữ liệu từ DataSet.

1 comment:

  1. Really no matter if someone doesn't be aware of afterward its up to other people that they will help, so here it occurs.

    Look at my page: natural cellulite treatment

    ReplyDelete