Bây giờ bạn sẽ tìm hiểu đầy đủ về việc DataSet lưu trữ một DataTable, truy nhập dữ liệu, và giám sát việc thi hành một số mẫu của những ràng buộc dữ liệu. Trong mục này chúng ta xây dựng dựa vào kiến thức đã biết và học thực hiện những thao tác về cơ
sở dữ liệu quan hệ chung với dữ liệu được lưu trũ trong DataSet.
3.5.1 Xuất phát từ những giá trị DataColumn cùng với biểu thức và các trường tính tốn.
Những giá trị của một DataColumn cĩ thể được tính tốn dựa trên giá trị
DataColumn khác trong cùng DataRow. Để làm điều này, ta sử dụng thuộc tính DataColumn.Expression để mơ tả giá trị tính tốn của DataColumn. Thuộc tính Expression là một giá trị kiểu string, nĩ mơ tả việc tính tốn xuất phát từ giá trị của DataColumn.
Cú pháp của biểu thức rất nhiều và được hỗ trợ một tập hợp rất phong phú về các phép tính tốn học và chuỗi. Bảng 6.1 trình bày tất cả các tốn tử của biểu thức mà được hỗ trợ bởi .NET Compact Framework.
Bảng 3.1. Những tốn tử của biểu thức được hỗ trợ bởi Framework Tốn Tử Chức Năng Sum Tính tổng của các đối số Avg Tính trung bình các đối số Min Lựa chọn giá trị nhỏ nhất của các đối số Max Lựa chọn giá trị lớn nhất của các đối số +, -, *, / Các phép tính: cộng, trừ, nhân, chia % Chia lấy số dư (phần cịn lại của phép chia) + Ghép chuỗi Ví dụ tạo biểu thức.
Cách dễ dàng nhất để hiểu “việc tạo một biểu thức như thế nào?” là xem một ví dụ. Cho ví dụđẩu tiên của chúng ta hãy xem một DataTable được gọi là l_newTable mà nĩ cĩ ba cột được đặt tên là: FirstName, LastName, và FullName. Mục đích của việc tạo một biểu thức mà đặt cột tên là FullName để ghép chuỗi của cột FirstName và cột LastName lại với nhau. Code sau đây sẽ trình bày việc làm này:
C#
Cho ví dụ thứ hai, ta sẽ xem một DataTable được đặt tên là l_newTable.Chúng tơi muốn đưa cột TotalPrice vào để lưu giá trị của cột MSRP trừđi giá trị của cột Discount.
C#
l_newTable.Columns["TotalPrice"].Expression = "MSRP - Discount";
ví dụ cuối cùng, l_newTable được xem là một DataTable với bốn cột: FinalGrade, Exam1, Exam2, và Exam3. Chúng tơi muốn đặt giá trị của cột FinalGrade bằng giá trị
trung bình của Exam1, Exam2, và Exam3, nhưđoạn code sau:
C#
l_newTable.Columns["FinalGrade"].Expression = "Avg(Exam1, Exam2, Exam3)";
3.5.2 Biểu diễn mối quan hệ Cha – Con tring một DataSet
Thành phần chủ yếu của một CSDL quan hệ là các bảng với các hàng và khả năng tạo một mối quan hệ Cha – Con, hoặc một mối quan hệ giữa hai bảng với nhau. Một mối quan hệ giữa hai bảng được làm bằng cách liên kết hai bảng bởi một hoặc nhiều cột dữ
liệu được làm khố chính. Trong bảng cha, khố chính (primary key) là duy nhất cho tất cả các hàng trong bảng. Các hàng trong bảng con cĩ một cột gọi là khố ngoại (foreign key), nĩ khơng phải là duy nhất trong bảng con. Nĩ nhằm vào hàng tương ứng trong bảng cha.
Ví dụ, xem bảng 3.2, một bảng cha lưu thơng tin chính về ngươi bệnh cho một văn phịng của thầy thuốc.
Table 3.2. MainContactTable
COLUMN NAME DATA TYPE
CustID Integer, PRIMARY KEY
FirstName String
LastName String
Bảng 3.3: Một bảng con lưu ngiên cứu về cholesterol.
Table 3.3. CholesterolTable
COLUMN NAME DATA TYPE
CustID Integer, FOREIGN KEY
Reading1 Decimal
Reading2 Decimal
Table 3.3. CholesterolTable
COLUMN NAME DATA TYPE
Average Decimal
Trong bảng CholesterolTable thì cột CustID cĩ là cột duy nhất tham chiếu tới bảng MainContactTable. Bảng 3.4 và 3.5 cho thấy mối quan hệ cha – con khi lưu trữ.
Table 3.4. MainContactTable
CustID FirstName LastName
001 George Washington
002 Ben Franklin
003 Alexander Hamilton
Table 3.5. CholesterolTable
CustID Reading1 Reading2 Reading3 Average
001 87 78 66 77.0
001 99 54 89 80.667
002 90 88 55 77.667
Trong bảng cha – con ở ví dụ này, cĩ hai mục (bản ghi) trong bảng CholesterolTable cho George Washington và một mục cho Ben Franklin. Chuyện gì sẽ
xảy ra nếu bản ghi của George Washington bị xố trong bảng MainContactTable? Hệ
thống phải xố tất cả những bản ghi tương ứng trong CholesterolTable hoặc cơ sở dữ liệu sẽ bị hỏng.
3.5.3 Tạo một DataRelation cho việc biểu diễn quan hệ cha – con.
Khi bạn thiết đặt một DataRelation giữa hai bảng, bạn phải chỉ định rõ DataColumn như khĩa chính, khố ngoại. Sau khi DataRelation được tạo, nĩ sẽ bảo đảm dữ liệu quan hệ của DataSet, nhưđược mơ tả bởi DataRelation. Ví dụ, nếu bạn xố hàng
đầu tiên từ bảng MainContactTable, thì DataRelation tự động xố tất cả các hàng con trong CholesterolTable.
Để thiết lập một DataRelation giữa hai bảng trong một DataSet, thì đầu tiên tạo một DataRelation bằng cách sử dụng hàm tạo thơng qua DataColumn mà bao gồm khố chính và khố ngoại. Các hàm tạo trong .NET Compact Framework như sau:
• DataRelation(String relName, DataColumn parent, DataColumn child): tạo một
tên DataRelation giữa DataColumns cha và con.
• DataRelation(String relName, DataColumn[] parent, DataColumn[] child): tạo
một tên DataRelation giữa hai bảng bằng cách sử dụng nhiều cột cho mỗi bảng của quan hệ.
• DataRelation(String relName, DataColumn parent, DataColumn child, bool
createConstraints): tạo một DataRelation giữa DataColumns cha và con.
• DataRelation(string relName, DataColumn[] parent, DataColumn[] child, bool
createConstraints): tạo một DataRelation giữa hai bảng bằng cách sử dụng nhiều cột cho mỗi bảng của quan hệ, với tùy chọn rõ ràng để tạo ra những ràng buộc kết hợp với việc thi hành quan hệ.
• DataRelation(string relName, string parentTableName, string childTableName,
string[] parentColNames, string[] childColNames, bool isNested): Là hàm tạo đã sử dụng mơi trường Smart Device Extensions.
Sau đĩ ta dễ dàng thêm DataRelation cho tập hợp DataSet.Relations.
3.5.4 Viết code để tạo một DataRelation
Đây là code mẫu được lấy từ code của ứng dụng PhoneBook, nĩ mơ tả việc sử
dụng các lớp Expression và DataRelation. Code tạo một DataRelation mới mà nĩ nối kết cột ContactID từ bảng PhoneContactsMainTable và bảng Cholesterol bên trong DataSet.
C#
DataRelation l_newRelation = new DataRelation( "MainContactToCholesterolRelation",
l_DataSet.Tables["PhoneContactsMainTable"].Columns["ContactID"], l_DataSet.Tables["Cholesterol"].Columns["ContactID"]);
l_DataSet.Relations.Add(l_newRelation);
3.5.5 Ràng buộc những quan hệ khố ngoại bằng ForeignKeyConstraint
ForeignKeyConstraint rất giống DataRelation nhưng nĩ cung cấp thêm tính linh hoạt. Như với một UniqueConstraint, thì ForeignKeyConstraint được thêm vào cho một tập hợp DataTable.Constraints. Một cách cụ thể hơn, ForeignKeyConstraint được thêm vào cho tập hợp Constraints của bảng con.
Khi một hàng con bị xố từ một bảng cha thì ForeignKeyConstraint cĩ thể gây ra những trường hợp sau:
• Nĩ cĩ thể gây ra tất cả những hàng con sẽ bị xố. Việc làm đĩ cũng giống như sử
dụng một DataRelation..
• Nĩ cĩ thể đặt các giá trị cột con, khố ngoại, giá trị NULL. Như vậy, chúng
• Nĩ cĩ thểđặt giá trị cột con một giá trị mặc định. Điều này là cĩ ích. • Nĩ cĩ thểđưa ra ngoại lệ.
Để đặt một ForeignKeyConstraint, đầu tiên ta tạo một ForeignKeyConstraint thơng qua các hàm tạo sẵn cĩ trong .NET Compact Framework. Các hàm tạo sẵn cĩ trong .NET Compact Framework được liệt kê dưới đây:
• ForeignKeyConstraint(DataColumn parentCol, DataColumn childCol): tạo
một ForeignKeyConstraint giữa DataColumns cha và con.
• ForeignKeyConstraint(String name, DataColumn parentCol, DataColumn
ChildCol): tạo một ForeignKeyConstraint giữa bảng cha và bảng con, nhưng bắt buộc đưa ra một tên.
• ForeignKeyConstraint(DataColumn[] parentCols, DataColumn[]
childCols): tạo một ForeignKeyConstraint giữa hai bảng bằng cách sử dụng nhiều DataColumn cho ràng buộc.
• ForeignKeyConstraint(String name, DataColumn[] parentCols,
DataColumn[] childCols): tạo một ForeignKeyConstraint giữa hai bảng bằng cách sử dụng nhiều DataColumns cho nhiều ràng buộc, nhưng mọi ràng buộc trở thành một tên.
• ForeignKeyConstraint(string cName, string pName, string[] pColNames,
string[] cColNames, AcceptRejectRule arRule, Rule dRule, Rule uRule):
được sử dụng trng mơi trường Smart Device Extensions.
Tiếp theo đặt DeleteRule, UpdateRule, và AcceptRejectRule của ForeignKeyConstraint. UpdateRule kiểm tra điều gì xảy ra khi một hàng cha bị sửa đổi. AcceptRejectRule kiểm tra điều gì xảy ra khi một hàng cha bị sửa đổi và hàm DataSet.AcceptChanges() được gọi. UpdateRule và DeleteRule là kiểu Rule trong khi AcceptRejectRule là một kiểu AcceptRejectRule.
Ví dụ, ta xem xét một ForeignKeyConstraint mà được sử dụng để biểu diễn một mối quan hệ giữa hai bảng. Nếu như một hàng từ bảng cha bị xố, thì giá trị của Delete
được kiểm tra xác định xem chuyện gì sẽ xảy ra với các bảng con: - Rule.Cascade: xố theo tầng, vì vậy các hàng con cũng được xố. - Rule.SetDefault: giá trị của các hàng con được đặt là DBNull. - Rule.None: một ngoại lệđược đưa ra.
AcceptRejectRule được kiểm tra chỉ khi DataSet.AcceptChanges được gọi. kiểu AcceptRejectRule cĩ hai giá trị: Cascade và None. Nếu AcceptRejectRule đặt giá trị là Cascade thì DataSet cố thay đổi tầng trong một hàng cha cho hàng con của nĩ khi DataSet.AcceptChanges được gọi.
Bây giờ ForeignKeyConstraint được thiết đặt. Để sử dụng nĩ, ta thêm vào cho ForeignKeyConstraint tập hợp Constraints của bảng con.
Tạo một ForeignKeyConstraint với code mẫu.
Code mẫu dưới đây tạo một ForeignKeyConstraint mà xếp tầng khi một hàng cha bị xố. Điều đĩ cĩ nghĩa là khi một hàng cha bị xố thì các hàng con cũng bị xố. Ta xem code dưới đây :
C#
ForeignKeyConstraint l_ForeignKC = new
ForeignKeyConstraint("MainToCholesterolFKConstraint", l_DataSet.Tables["PhoneContactsMainTable"].Columns ["ContactID"], l_DataSet.Tables["BloodPressure"]. Columns["ContactID"]); l_ForeignKC.DeleteRule = Rule.Cascade; l_ForeignKC.UpdateRule = Rule.Cascade; l_ForeignKC.AcceptRejectRule = AcceptRejectRule.Cascade; l_DataSet.Tables["BloodPressure"].Constraints.Add(l_ForeignKC); l_DataSet.EnforceConstraints = true; 3.6 Tạo các khung ràng buộc của dữ liệu với một DataView
Từ trên cho thấy, dữ liệu được rút từ một DataTable để truy cập tập hợp DataTable.Rows. Mỗi một DataRow trong tập hợp DataTable.Rows cĩ những đối tượng DataColumn mà cĩ thể được chỉ số hĩa bởi tên hay số. ứng dụng mẫu đầu tiên trong chương này trình bày quá trình lặp lại thơng qua tập hợp DataTable.Row để khảo sát dữ
liệu.
Mặc dù đĩ là một cách cĩ hiệu quả trong việc truy nhập dữ liệu ở trong một DataTable, nhưng nĩ khơng cung cấp một cách thức dễ dàng cho việc phân loại dữ liệu dựa vào một cột đặc biệt hay lọc các hàng. Chỉ riêng DataRows trong tập hợp DataTable.Rows là thấy được.
Lớp DataView là một phương pháp đúng để xem kỹ nội dung của một DataTable trong một lựa chọn and/or được lọc theo định dạng. Nhìn từ bên ngồi DataView rất giống một DataTable. Nĩ cĩ một bộ chỉ số cho các hàng trong một DataView , và mỗi hàng bên trong DataColumnS cĩ thểđược truy nhập và thao tác một cách thơng thường.
Ngồi ra DataView cũng cĩ một đối tượng ràng buộc dữ liệu . Điều này cĩ nghĩa rằng nĩ cung cấp dụng cụ chung mà cho phép DataView trở thành nguồn dữ liệu cho những đối tượng khác mà cĩ thể thao tác những đối tượng dữ liệu ràng buộc. Đặc biệt, bạn cĩ thể sử dụng DataView để lưu trữ một DataGrid với nội dung của một DataView. Sau khi bạn đã thiết lập một mối quan hệ giữa một DataView và một DataGrid, thì nội
dung của DataGrid là nội dung (giới hạn) của DataView. DataGrid trình bày nội dung của DataGrid, và tựđộng duy trì ngày tháng hiển thị khi DataView thay đổi.
Ví dụ, bạn cĩ thể tạo một DataView thích hợp bằng cột Age của một DataTable và nối kết nĩ với một DataGrid. DataGrid trình bày nội dung của DataView. Nếu ứng dụng đưa vào nhiều dữ liệu hơn thì DataGrid sẽ tựđộng cập nhật nội dung.
Những hạn chế của DataGrid: DataGrid cĩ mặt trong .NET Compact Framework, nhưng nĩ là một phiên bản bị cắt giảm nhiều so với DataGrid của máy để bàn.
3.6.1 Sắp xếp với DataView
Để sắp xếp dữ liệu trong một DataTable ta sử dụng một DataView, và làm theo các bước sau:
1. Tạo một DataView mới.
2. Thiết đặt thuộc tính Sort của DataView mới tạo. Thuộc tính Sort là một chuỗi. Thêm thuộc tính DESC giới hạn cho việc sắp xếp một cột theo thứ tự giảm dần và ngăn cách các cột bằng dấu phẩy.
Dưới đây là đoạn code mẫu được lấy ra từứng dụng DataView_Sort_And_Filter mẫu. Nĩ tạo một DataView mới từ bảng đầu tiên trong một DataSet. Nĩ sắp xếp tuổi theo thứ tự giảm dần, sau đĩ đến sắp xếp tên và cuỗi cùng nĩ đưa vào DataRows.
C#
DataView l_sortAgeView = new DataView(in_DataSet.Tables[0]); l_sortAgeView.Sort = "Age DESC, Name DESC";
for (int i = 0; i < l_sortAgeView.Count; i++) {
this.listBox2.Items.Add(l_sortAgeView[i]["Name"] + " " + l_sortAgeView[i]["Age"]);
}
3.6.2. Kiểm tra sự thay đổi trong một DataRow
Mọi DataRow được đưa vào từ một DataTable hoặc một DataView đều cĩ một thuộc tính được gọi là RowState. RowState cĩ kiểu DataRowState.
- Unchanged: DataRow khơng được thay đổi từ lần gần đây nhất, AcceptChanges
được gọi trên DataSet mà nĩ chứa DataRow
- Original: Chuyển tới tất cả các hàng gốc mà nĩ khơng thay đổi hay đã bị xĩa từ
lần gần nhất, AcceptChanges được gọi trên DataSet mà chứa DataRow.
- CurrentRows:Tất cả những hàng sẵn cĩ trong DataRow hay DataView, kể cả là hàng mới thêm vào, xố đi, hay là thay đổi từ lần gần nhất. Phương thức AcceptChanges
được gọi trên DataSet mà chứa DataRow. Nếu những hàng đã được sửa đổi, thì giá trị
- Added:phương thức này được sử dụng khi DataRow đã được thêm vào tập hợp DataTable.Row từ lần lần gần đây mà AcceptChanges được gọi trên DataSet mà chứa DataRow.
- Deleted phương thức này được sử dụng khi DataRow đã được xố khỏi tập hợp DataTable.Row từ lần lần gần đây mà AcceptChanges được gọi trên DataSet mà chứa DataRow.
- ModifiedCurrent Tham chiếu tới dữ liệu hiện thời trong những hàng mà đã được sửa đổi từ lần gần nhất AcceptChanges được gọi trên DataSet mà chứa DataRow.
- None Tham chiếu đến giá trị none của DataRows
3.6.3 Lọc dữ liệu với DataView
Ta cĩ thể sử dụng DataView để lọc ra một số hàng mà ta muốn. Để thiết đặt một DataView lọc dữ liệu theo trạng thái RowState của nĩ ta đặt thuộc tính DataView.RowStateFilter cho một trong các giá trị DataRowState
3.6.4 Thêm dữ liệu vào trong một DataView
DataRows mới cĩ thể được thêm vào cho một DataView và sau đĩ được lọc cho DataTable nguồn. Điều này cĩ thể là một chức năng thuận tiện trong các ứng dụng giao dịch mà thao tác dữ liệu của chúng gần như thơng qua các lớp DataView. Để thêm mới một DataRow cho một DataView cĩ sẵn và lọc nĩ cho DataTable gốc, ta làm theo các bước sau:
1. Tạo một DataRowView bằng cách gọi hàm DataView.AddNew() trên DataView mà nĩ được sử dụng để thêm một hàng mới.
2. Đưa vào các giá trị cho DataColumns của DataRowView.
3. Gọi hàm DataRowView.EndEdit(). Đây là hàm mà bạn được kết thúc việc thiết
đặt DataRowView mới nhưng khơng gọi thuộc tính AcceptChanges trên DataSet cha.
Dưới đây là đoạn code mẫu thực hiện theo các bước trên:
C#
int l_maxRandom = 100;
// Step 1 - Create instance of the DataRowView
DataRowView l_firstNewDataRowView = m_addedRowsView.AddNew();
// Step 2 - Set column values
l_firstNewDataRowView["Name"] = "NewPerson" + m_Random.Next(l_maxRandom).ToString();
// Step 3 – call EndEdit()
l_firstNewDataRowView.EndEdit();
Đoạn code: Thêm và xố DataRows thơng qua một DataView
C#
// Delete two rows
m_DataSet.Tables[0].Rows[0].Delete(); m_DataSet.Tables[0].Rows[1].Delete();
// Add two new rows int l_maxRandom = 100;
DataRowView l_firstNewDataRowView = m_addedRowsView.AddNew();
l_firstNewDataRowView["Name"] = "NewPerson" + m_Random.Next(l_maxRandom).ToString();
l_firstNewDataRowView["Age"] = m_Random.Next(l_maxRandom);
l_firstNewDataRowView.EndEdit();
DataRowView l_secondNewDataRowView = m_addedRowsView.AddNew();
l_secondNewDataRowView["Name"] = "NewPerson" + m_Random.Next(l_maxRandom).ToString(); l_secondNewDataRowView["Age"] = m_Random.Next(l_maxRandom); l_secondNewDataRowView.EndEdit(); 3.7. Gán dữ liệu cho một điều khiển. Gán dữ liệu cho một DataGrid
Khi một DataSet được giới hạn vào một DataGrid, thì nội dung của DataSet tự động xuất hiện trên DataGrid. Để gán dữ liệu của một DataSet cho một DataGrid, ta làm theo các bước sau:
1. Tạo một DataView
2. Tạo một DataGrid mới bằng cách kéo điều khiển DataGrid từ hộp toolbar. 3. Thiết đặt thuộc tính DataGrid.DataSource cho DataView mà bạn đã tạo ở trên
Đoạn code mẫu dưới đây sẽ trình bày việc gán một DataGrid với một DataView.
C#
// Assuming that m_DataSet was already set up...
m_sortAgeDataView = new DataView(m_DataSet.Tables[0]); m_sortAgeDataView.Sort = "Age DESC, Name DESC"; // Bind the DataGrid to our DataView and it will // automatically paint itself!
Chương 4: Lập trình với Microsoft SQL Server CE
4.1 Tìm hiểu các tính chất hỗ trợ bởi Microsoft SQL Server 2000 Windows CE Edition Windows CE Edition
Ngơn ngữ truy vấn cĩ cấu trúc (SQL) Server 2000 Windows CE Edition (SQL Server CE) rất nhỏ so với bộ máy CSDL Microsoft's SQL Server 2000. Mặc dù kích cỡ
của nĩ như vậy, nhưng SQL Server CE cung cấp đủđể lưu trữ dữ liệu và các chức năng. SQL Server CE hỗ trợ CSDL cĩ dung lượng lớn nhất đến 2GB. SQL Server CE hỗ trợ tập con các ngơn ngữ định nghĩa dữ liệu và ngơn ngữ thao tác dữ liệu. Cĩ hỗ trợ
nhiều cột chỉ số, khĩa chính, ràng buộc.
Khi phát triển ứng dụng SQL Server CE, chúng ta cần phải thêm hai assembly references để dự án của chúng ta làm việc nhưđoạn mã. SQL Server CE quản lý sự tồn