Chương 4 ADO.NET trên .NET CompactFramework
5.5 Lấy dữ liệu bằng SqlCeDataReader
5.5.1 Lấy dữ liệu bằng SqlCeDataReader
Dữ liệu có thể được lấy CSDL SQL CE bằng cách sử dụng lớp SqlCeDataReader. Lớp
SqlCeDataReader cung cấp truy nhập nhanh, chỉ một hướng về phía trước tới các bản ghi dữ
liệu.
Các bước để nhận dữ liệu bằng SqlCeDataReader như sau:
Bươc 1: Tạo một thể hiện SqlCeConnection. SqlCeDataReader sẽ sử dụng kết nối để
nhận dòng dữ liệu yêu cầu.
Bước 2: Đối tượng SqlCeCommand sẽ được tạo cùng vi câu lệnh SELECT thích hợp. Bước 3: Thiết lập kiểu câu lệnh, và gọi phương thức SqlCeCommand.ExecuteReader.
Phương thức ExecuteReader thực thi command text đối với CSDL bằng SqlCeConnection. SqlCeDataReader sẽ cung cấp truy cập dữ liệu để trả về dữ liệu được trả về. SqlCeConnection sẽ bận will SqlCeDataReader đến khi q trình đọc dữ liệu đóng lại.
Phương thức đưa đến một tham số của kiểu CommandBehavior. Kiểu CommandBehavior là một tập hợp mà SqlCeCommand sử dụng. Bảng 5.8 là danh sách giá trị của CommandBehavior bà mô tả.
Bảng5.8. Giá trị CommandBehavior
Tên Mô tả
CloseConnection Kết nối được đóng lại sau khi đọc dữ liệu được đóng.
Default Truy vấn có thể trả về nhiều tập kết quả.
KeyInfo Truy vấn trả về thơng tin của cột và khóa chính. Truy vấn được thực thi mà
khơng có bất kỳ dịng nào lựa chọn bị khóa
SchemaOnly Truy vấn trả về thông tin của cột.
SequentialAccess Truy vấn cung cấp một cách cho DataReader thao tác các hàng chứa đựng các cột có giá trị nhị phân lớn.
SingleResult Truy vấn trả về một tập kết quả đơn.
SingleRow Truy vấn trả về một dịng. Nó chỉ ra vị trí của SingleRow khi thực thi truy
vấn mà kết quả là tập hợp nhiều kết quả. Trong trường hợp này, kết quả trả về là tập nhiều kết quả, mỗi kết quả trả về là một dòng.
Một SqlCeDataReader được trả về dựa vào gọi ExecuteReader. Sự tiến bộ của phương thức là đọc các bản ghi tiếp theo. SqlCeDataReader có vị trí khởi tạo là trước bảng ghi đầu tiền. Vì vậy phải gọi Read trước khi yêu cầu lấy dữ liệu. Phương thức Read sẽ trả về true đến tận khi
SqlCeDataReader đến cuối của tập kết quả trả về. Sau đó tả về kết quả false.
Chúng xác định được vị trí dịng dữ liệu, chúng ta có thể sử dụng các phương thức
GetXXX của SqlCeDataReader để truy nhạp các cột trong mỗi dòng dữ liệu. Phương thức
GetInt32 nhận một giá trị Int32 từ một cột trong dòng hiện tại của SqlCeDataReader. Phương
thức đưa đến một tham số kiểu int. Tham số này thể hiện số thứ tự của cột. Nếu thứ tự của cột không biết đến khi tiết kế, chúng ta có thể sử dụng phương thức GetOrdinal để tìm số thứ tự của cột bằng tên cột. Trong Listing 5.6 mô tả cách nhận tất cả thông tin từ bảng Package.
Listing 5.6 Nhận tất cả thông tin trong bảng Package
public static void GetAllPackageInfo() { string pckgStr =
"Package Data\nID: {0}\nCode: {1}\nDestination: {2}"; string connstr = @"Data Source=\My Documents\PTSystem.sdf"; using(SqlCeConnection conn = new SqlCeConnection(connstr)) { conn.Open();
string dmlPackageInfo = "SELECT * FROM Package"; SqlCeCommand cmdGetPackageInfo = null;
SqlCeDataReader drPackageInfo = null; try {
cmdGetPackageInfo = new SqlCeCommand(dmlPackageInfo, conn); cmdGetPackageInfo.CommandType = CommandType.Text; drPackageInfo = cmdGetPackageInfo.ExecuteReader(CommandBehavior.Default); while(drPackageInfo.Read()) { System.Windows.Forms.MessageBox.Show( string.Format(pckgStr, drPackageInfo.GetInt32(0),
drPackageInfo.GetString(1), drPackageInfo.GetString(2))); }
} catch(SqlCeException scee) {
for(int curExNdx = 0; curExNdx < scee.Errors.Count; ++curExNdx) { System.Windows.Forms.MessageBox.Show(
"Error:"+ scee.Errors[curExNdx].ToString()+"\n"); }
} finally {
if( cmdGetPackageInfo != null ) cmdGetPackageInfo.Dispose(); if( drPackageInfo != null ) drPackageInfo.Close(); }
} }
5.5.2 Sử dụng tham số SQL Commands
Câu lệnh SELECT sử dụng trong Listing 5.5 rất đơn giản. Trong các câu lệnh SELECT sẽ hầy hết sử dụng mệnh đề WHERE, cái đó sẽ giúp chúng ta lấy những dịng cần thiết. Chúng ta có thể sử dụng mệnh đề WHERE để lựa chọn thơng tin trong bảng Package. Một ví dụ về truy SELECT:
SELECT * FROM Package WHERE ID = "0987654321"
Truy vấn này SELECT lấy về những dịng có cột ID có giá trị 0987654321.
Chúng ta hãy tạo một đối tượng SqlCeCommand. Đối tượng SqlCeCommand cung cấp
thuộc tính Parameters chứa đựng tập hợp tất cả các tham số. Để thêm tham số vào tập hợp này chúng ta sử dụng phương thức SqlCeCommand.Prepare.
Listing 5.7 Thực thi một tham số SQL command
public static void GetPackageInfo(int pckgID) { string pckgStr =
"Package Data\nID: {0}\nCode: {1}\nDestination: {2}"; string connstr = @"Data Source=\My Documents\PTSystem.sdf"; using(SqlCeConnection conn = new SqlCeConnection(connstr)) { conn.Open();
string dmlPackageInfo = "SELECT * FROM Package WHERE ID = ?"; SqlCeCommand cmdGetPackageInfo = null;
SqlCeDataReader drPackageInfo = null; try {
cmdGetPackageInfo = new SqlCeCommand(dmlPackageInfo, conn); cmdGetPackageInfo.CommandType = CommandType.Text; cmdGetPackageInfo.Parameters.Add("ID", pckgID); cmdGetPackageInfo.Prepare(); drPackageInfo = cmdGetPackageInfo.ExecuteReader(CommandBehavior.SingleRow); while(drPackageInfo.Read()) { System.Windows.Forms.MessageBox.Show( string.Format(pckgStr, drPackageInfo.GetInt32(0),
drPackageInfo.GetString(1), drPackageInfo.GetString(2))); }
} catch(SqlCeException scee) {
for(int curExNdx = 0; curExNdx < scee.Errors.Count; ++curExNdx) { System.Windows.Forms.MessageBox.Show(
"Error:"+ scee.Errors[curExNdx].ToString()+"\n"); }
} finally {
if( cmdGetPackageInfo != null ) cmdGetPackageInfo.Dispose(); if( drPackageInfo != null ) drPackageInfo.Close(); }
} }
Truy vấn có tham số có thể được sử dụng trong hầu hết các câu SQL, DDL và DML. Nó có thể được sử dụng nhiều hơn một tham số trong truy vấn. Ví dụ, truy vấn sau có thể được sử dụng để SELECT.
SELECT * FROM Package WHERE Code = ? OR DestinationID = ?
Khi sử dụng câu lệnh SELECT cùng với nhiều tham số, chúng ta phải thêm đối tượng SqlCeParameters vào tập hợp Parameters theo thứ tự dấu ? xuất hiện từ trái sang phải.
Listing 5.8 Thực thi SQL command cùng với nhiều tham số
public static void GetPackageInfo(int[] pckgID) { string pckgStr =
"Package Data\nID: {0}\nCode: {1}\nDestination: {2}"; string connstr = @"Data Source=\My Documents\PTSystem.sdf"; using(SqlCeConnection conn = new SqlCeConnection(connstr)) { conn.Open();
string dmlPackageInfo = "SELECT * FROM Package WHERE ID = ?"; SqlCeCommand cmdGetPackageInfo = null;
SqlCeDataReader drPackageInfo = null; try {
cmdGetPackageInfo = new SqlCeCommand(dmlPackageInfo, conn); cmdGetPackageInfo.CommandType = CommandType.Text; cmdGetPackageInfo.Parameters.Add("ID", SqlDbType.Int); cmdGetPackageInfo.Prepare(); for(int pckgNdx = 0; pckgNdx < pckgID.Length; ++pckgNdx) { cmdGetPackageInfo.Parameters[0].Value = pckgID[pckgNdx]; try { drPackageInfo = cmdGetPackageInfo.ExecuteReader(CommandBehavior.SingleRow); while(drPackageInfo.Read()) { System.Windows.Forms.MessageBox.Show( string.Format(pckgStr, drPackageInfo.GetInt32(0), drPackageInfo.GetString(1), drPackageInfo.GetString(2))); } } catch(SqlCeException scee) {
for(int curExNdx=0;curExNdx<scee.Errors.Count;++curExNdx) { System.Windows.Forms.MessageBox.Show(
"Error:"+ scee.Errors[curExNdx].ToString()+"\n"); }
} finally {
if( drPackageInfo != null ) drPackageInfo.Close(); }
}
} finally {
if( cmdGetPackageInfo != null ) cmdGetPackageInfo.Dispose(); }
}
}