校驗DataSet中的數據
數據庫提供了很多的機制使數據是有效的。ADO.NET的DataSet提供了許多可在數據庫系統中使用的相同的數據效驗機制。一般可以將這些效驗的機制分成兩類:列級別的限制和表級別的效限制。列級別的限制:驗證DataColumn的屬性
DataColumn對象提供了許多能用來驗證數據的屬性:
ReadOnly:確保數據是否讓用戶修改
AllowDBNull:一些數據庫的列是否可為Null
MaxLength:最多接受字符串的長度
Unique:是否要求該列是不可重復的
表級別的限制:DataTable類的Constraints集合
ADO.NET對象模型包括兩個類,可以用他們在DataTable中定義約束。這兩個類是UniqueConstraints和ForeignkeyConstraint,他們都是派生於Constraints類的。DataTable公開一個Constraints屬性,使用該屬性可以添加、修改或查看DataTable上的約束。
UniqueConstraints
如果將DataColumn的Unique屬性設置為True,也就在包含該列的DataTable定義了一個唯一的約束。同時還將UniqueConstraints對象加到DataTable對象的Constraints集合中。設置DataColumn的Unique屬性比在DataTable對象的Constraints集合中創建一個新的UniqueConstraint要簡單,但是在有些時候會需要顯示創建UniqueConstraint,例如在需要確保多列合並之后的值為唯一時。
Primarykey
DataTable類允許通過Primarykey屬性為DataTable定義一個主鍵,Primarykey屬性包含的是一個DataColumn對象數組,DataTable使用該數組來構造一個UniqueConstraint,以支持
約束。
ForeignkeyConstraint
外部的約束添加到DataTable中。通常可能不需要顯示創建ForeignkeyConstraint。在DataSet內的兩個DataTable對象之間創建DataRelation也會創建一個ForeignkeyConstraint。
DataRow.RowState屬性
DataSet中的一切都是一種脫機緩存,在DataSet所作的一切修改要是不提交數據庫的話,那么用途也不是很大。那么在DataSet中修改是會有記錄的,這些記錄在DataRow.RowState屬性中,DataRow.RowState使用的是一個枚舉中的值:
Unchanged 該行未包含任何掛起更新
Detached 該行不是DataTable的一個成員
Added 該行已經被添加到了DataTable中,但是不存在在數據庫中
Modified 該行被掛起更改
Deleted 該行為掛起刪除
例子:
Unchanged row = tb1.NewRow;row["lmf"] = "liumingfeng";
Detached row.Rows.Add(row);
Added row = tb1.Rows(0);
Modified row["lmf"] = "hello world";
Deleted row.Delete();
一般來說,DataRow有兩個版本,一個是當前的行內容,一個是原來存儲在該行的內容。
可以這樣來查看不同的版本的內容:
row["lmf",DataRowVersion.Current];//當前的值
row["lmf",DataRowVersion.Original];//原來的值
創建DataRelation對象
在創建DataRelation時,應該提供一個名稱,這樣就可以在其集合中查找該對象,並且指定該關系所基於的父列和子列。DataRelation有不同的構造函數來接受單個的DataColumn或者是DataColumn對象數組。最后增加在DataSet中的Relations屬性中,Relations屬性是DataRelation的集合。
用單個的DataColumn創建DataRelation:
//創建數據庫結構
DataSet ds = new DataSet("MyDataSet");
DataTable tb1 = ds.Tables.Add("Customers");
tb1.Columns.Add("CustomerID",typeof(string));
tb1.Columns.Add("CustomerName",typeof(string));tb1 = ds.Tables.Add("Orders");
tb1.Columns.Add("OrderID",typeof(int));
tb1.Columns.Add("CustomerID",typeof(string));
tb1.Columns.Add("OrderDate",typeof(DateTime));//添加用單個的DataColumn創建DataRelation
DataRelation rel;
rel = new DataRelation("Customer_Orders",ds.Table["Customers"].Columns["CustomerID"],ds.Table["Orders"].Columns["CustomerID"]);
ds.Relations.Add(rel);
如果希望根據多個字段定義DataRelation,那么就要使用接受DataColumn對象數組的構造函數,代碼示例:
//創建數據庫結構
DataSet ds = new DataSet("MyDataSet");
DataTable tbCustomer = ds.Tables.Add("Customers");
tbCustomer.Columns.Add("CustomerID",typeof(string));
tbCustomer.Columns.Add("CustomerName",typeof(string));DataTable tbOrder = ds.Tables.Add("Orders");
tbOrder.Columns.Add("OrderID",typeof(int));
tbOrder.Columns.Add("CustomerID",typeof(string));
tbOrder.Columns.Add("CustomerName",typeof(string));
tbOrder.Columns.Add("OrderDate",typeof(DateTime));//創建引用DataColumn對象的數組
DataColumn[] CustomerP,OrderC;
CustomerP = new DataColumn[]{tbCustomer.Columns["CustomerID"],tbCustomer.Columns["CustomerName"]};
OrderC = new DataColumn[]{tbOrder.Columns["CustomerID"],tbOrder.Columns["CustomerName"]};//添加用單個的DataColumn創建DataRelation
DataRelation rel;
rel = new DataRelation("Customer_Orders",CustomerP,OrderC);
ds.Relations.Add(rel);
以上的方法都是:先創建一個DataRelation對象,然后再添加到DataSet中的Relations集合中。這個模式和新建的DataTable、DataColumn對象一樣的。
還可以使用語法糖:
ds.Relations.Add("Customer_Orders",ds.Table["Customers"].Columns["CustomerID"],ds.Table["Orders"].Columns["CustomerID"]);
DataRelation對象的用途
DataRelation對象屬於DataSet所有,記錄着DataTable與DataTable的關系,主要的用途是查找有關聯的DataTable中的數據。不過DataRelation不親自處理這個任務,至少不是直接的處理這個任務。這個功能實際上是通過DataRow對象的GetChildRows、GetParentRow和GetParentRows方法提供的。其實在調用這幾個方法時,需要DataRelation對象作為參數傳入,在這幾個方法的內部會引用DataRelation對象來獲取表之間的關系,來查找有關的數據的。
使用GetChildRows方法:
//創建數據庫結構
DataSet ds = new DataSet("MyDataSet");
DataTable tb1 = ds.Tables.Add("Customers");
tb1.Columns.Add("CustomerID",typeof(string));
tb1.Columns.Add("CustomerName",typeof(string));tb1 = ds.Tables.Add("Orders");
tb1.Columns.Add("OrderID",typeof(int));
tb1.Columns.Add("CustomerID",typeof(string));
tb1.Columns.Add("OrderDate",typeof(DateTime));//添加用單個的DataColumn創建DataRelation
DataRelation rel;
rel = new DataRelation("Customer_Orders",ds.Table["Customers"].Columns["CustomerID"],ds.Table["Orders"].Columns["CustomerID"]);
ds.Relations.Add(rel);//填充DataSet
string strConn,strSQL;
......
SqlDataAdapter da = new SqlDataAdapter(strSQL,strConn);
da.TableMapping.Add("Table","Customers");
da.TableMapping.Add("Table1","Orders");
da.Fill(ds);//遍歷客戶
foreach(DataRow row in ds.Tables["Customers"].Rows)
{
Console.WriteLine("{0}",row[0]);
//遍歷相關的訂單,使用GetChildRows方法
foreach(DataRow rowOrder in row.GetChildRows(rel))
{
Console.WriteLine("{0}--{1}",rowOrder["OrderID"],rowOrder["OrderDate"]);
}
Console.WriteLine();
}
調用GetChildRows方法的,可將DataRelation對象作為參數傳入,也可以使用DataRelation對象的名稱作為參數傳入。
使用GetParentRow方法:
//遍歷訂單
DataRow coustomer;
foreach(DataRow row in ds.Tables["Orders"].Rows)
{
//定位相關的父行,查找顧客
coustomer = row.GetParentRow("Customer_Orders");
}