4、DataSet
在ADO.NET中DataSet的作用是為資料來源提供一個斷開式的儲存,而不必關心資料來源,操作只用在DataSet中進行就行了。
有三種方法可以建立DataSet:1、通過DataAdapter 2、通過XML 檔案 3、用人工方法確定架構,然後逐行輸入資料。
主要介紹第一種方法。
DataAdapter用於將DataSet串連到基本資料存放區,本質上是一種元Command對象。
它包括SelectCommand對象,InsertCommand對象,UpdateCommand對象,DeleteCommand對象。
模板代碼:
Dim dataAdpater As New SqlDataAdapter("Select * From Student",conn)
Dim dataSet As New DataSet()
dataAdapter.Fill(dataSet)
這時dataSet的表名預設為Table
如果使用批處理查詢並將得到的結果填入dataSet中則表名預設為Table,Table1,Table2……
TableMappings:
表名映射:
產生dataAdapter之後再進行表名映射
dataAdapter.TableMappings.Add("Table","Customer")
dataAdapter.Fill(dataSet)
這時Table的別名就變為Customer(對dataSet用Table或Customer操作都可以),dataSet.Tables("Customer")就可以引用到這個表
或
dataAdapter.TableMappings.Add("ADONET","Customer")
dataAdapter.Fill(dataSet,"ADONET")
列名映射:
dataAdapter.TableMappings.Add("Table","Customer")
dataAdapter.TableMappings("Customer").ColumnMappings.Add("CustomerID","ID)
dataAdapter.FIll(dataSet,"Customer")
在dataAdapter中添加表名映射後,相對有兩個表,一個表是原先的表,另一個表是映射後的表,列名也經過相應的映射,因此在Fill時要 指定是哪個表,否則顯示的時候就不會顯示映射後的列名。另外在表名映射後,在資料繫結時只能指定dataMember為Student。
例子(綁定到DataGrid)
Dim conn As New SqlConnection("data source=localhost;initial catalog=StudentCourse;" & _
"User ID=;Password=;")
conn.Open()
Dim dataAdapter As New SqlDataAdapter("Select * From Student", conn)
conn.Close()
Dim dataSet As New DataSet
dataAdapter.TableMappings.Add("Table", "Student")
dataAdapter.TableMappings.Add("Student", "Student") //這一步不能省,否則在下面的列名映射時會提示找不到映射名為Student表
dataAdapter.TableMappings("Student").ColumnMappings.Add("Sno", "學號")
dataAdapter.TableMappings("Student").ColumnMappings.Add("Sname", "姓名")
dataAdapter.TableMappings("Student").ColumnMappings.Add("sex", "性別")
dataAdapter.TableMappings("Student").ColumnMappings.Add("classID", "班級號")
dataAdapter.TableMappings("Student").ColumnMappings.Add("age", "年齡")
dataAdapter.TableMappings("Student").ColumnMappings.Add("address", "地址")
dataAdapter.Fill(dataSet, "Student")
DataGrid1.DataSource = dataSet
DataGrid1.DataMember = "Student"
另一種添加映射的方法是建立DataTableMapping對象並把它添加到DataAdapter中
Dim conn As New SqlConnection("data source=localhost;initial catalog=StudentCourse;" & _
"User ID=sa;Password=firerainbow;")
conn.Open()
Dim dataAdapter As New SqlDataAdapter("Select * From Student", conn)
conn.Close()
Dim dataSet As New DataSet
Dim myMap As New DataTableMapping("Table", "Student")
myMap.ColumnMappings.Add("Sno", "學號")
myMap.ColumnMappings.Add("Sname", "姓名")
myMap.ColumnMappings.Add("sex", "性別")
myMap.ColumnMappings.Add("classID", "班級號")
myMap.ColumnMappings.Add("age", "年齡")
myMap.ColumnMappings.Add("address", "地址")
dataAdapter.TableMappings.Add(myMap)
dataAdapter.Fill(dataSet, "Table")
DataGrid1.DataSource = dataSet
DataGrid1.DataMember = "Student"
架構(Schema),通過FillSchema添加架構
1、添加主鍵
customerTable.PrimaryKey=New DataColumn[]{CustomerTable.Columns("CustomerID")} (通過數組的形式添加主鍵)
2、添加關係
dataSet.Relations.Add("Customers_Invoices",dataSet.Tables("Customers").Columns("CustomerID"),dataSet.Tables ("Invoinces").Columns("CustomerID"),true)
3、添加約束
有兩種主要約束:唯一約束、外碼約束(UniqueConstraint,ForeignKeyConstraint)
其中唯一約束又分為DeleteRule(串聯刪除約束)、UpdateRule(串聯更新約束)、AcceptRejectRule(調用AcceptChanges或 RejectChanges時的約束)
4、添加觸發器
可以對6中DataSet事件添加觸發器
RowChanging,RowChanged,ColumnChanging,ColumnChanged,RowDeleting,RowDeleted
5、列架構
比如添加列的屬性:customerTable.Columns("CustomerID").ReadOnly=true
或添加AutoIncrement列:
customerTable.Columns("CustomerID").AutoIncrement=true
customerTable.Columns("CustomerID").AutoIncrementSeed=1 (列起始位置)
customerTable.Columns("CustomerID").AutoIncrementStep=1 (列遞增步長)
可能有人會說這一切在DBMS裡面做不就行了嗎,幹嗎那麼大費周折的在ADO.NET對Dataset再寫一遍呢?
這主要是出於對效率方面的考慮,如果用戶端的錯誤輸入能在用戶端就被發現出來,而不用傳到服務端進行驗證的話就可以減少不必要的傳輸了。
運算式列:
Dim exColumn As New DataColumn("LineTotal")
exColumn.DataType=typeof(float)
exColumn.Expression="((price-(price*Discount))*Quantity)"
dataSet.Tables("items").Columns.Add(excolumn)