主要内容:
1. DataSet和DataAdapter簡介
1. DataAdapter用于從資料源檢索資料并填充
2. DataSet中的表。DataAdapter還可将DataSet所做更改解析回資料源
執行個體:
{
string constr = "server=root-pc; database=hrms; uid=sa; pwd=' 000000'";
SqlConnection conn = new SqlConnection(constr);
string sql = "select bh as 員工編号,xm as 姓名,xb from employee";
SqlDataAdapter sda = new SqlDataAdapter(sql, conn);
DataSet ds = new DataSet();
sda.Fill(ds);
dataGridView1.DataSource = ds.Tables[0];
}
2. 填充多張表到DataSet
SqlDataAdapter類有四個重載
SelecteCommand屬性
SelecteSqlconnection屬性
dataGridView控件的使用
行:Rows
列:Cells
填充表是使用DataAdapter對象的fill方法
DataSet是一個表的集合,可以存儲多張表
如:
SqlDataAdapter sda = new SqlDataAdapter(sql, conn);
DataSet ds = new DataSet();
sda.Fill(ds);
fill方法就是将通過連接配接對象和指令對象擷取的資料填充到DataSet對象中去。然後再通過DataSet對象中的表集合屬性讀取表中的資料。
如:
dataGridView1.DataSource = ds.Tables[0];
3. DataSet資料表與關系
DataSet多張表的表名存在大小寫區分
DataTable對象 和 DataRelation對象
DataTable是建立表的類
如:
DataTable tbl=new DataTable("users")
即建立了一個表名為users的表
表有行集和列集組成,是以通過tbl對象就可以調用Rows和Columns兩上集合,并從中讀取資料。
DataRow 和 DataColumn是定義表的行和列變量兩個資料類型。
如:
//建立表,并為此表添加列
DataTable dt2 = ds3.Tables.Add("NewTable2");
DataColumn col2 = dt2.Columns.Add("ID",typeof(int));//添加列
//定義列屬性
col2.AllowDBNull = false;//值不能為空
//col2.MaxLength = 10;//最大長度10
col2.Unique = true;//值的唯一性為真
//為表定義一個主鍵限制
dt2.PrimaryKey = new DataColumn[] { dt2.Columns["ID"] };
//添加一列
DataColumn col3 = dt2.Columns.Add("xm",typeof(int));
col3.AutoIncrement = true;//定義列的自增長屬性為真
col3.AutoIncrementSeed = 1;//自增長的種子為1
col3.AutoIncrementStep = 1;//增長的步幅為1
col3.ReadOnly = true;//定義此列為隻讀屬性
//再加一列
DataColumn col4 = dt2.Columns.Add("sum",typeof(int),"ID*xm");
//======================================================
//往表中添加行
DataRow r1 = ds3.Tables["NewTable2"].NewRow();
r1[0] = 100;//為行的第一列指派
object[] z = { 100};//定義object對象集合,存儲行中的各列的值
ds3.Tables["NewTable2"].LoadDataRow(z, false);
label3.Text = dt2.Rows[0][dt2.Columns[0]].ToString();
label3.Text += "\n"+dt2.Rows[0][dt2.Columns[1]].ToString();
label3.Text += "\n" + dt2.Rows[0][dt2.Columns[2]].ToString();
注意:也可以以執行個體化的式建立行和列
如:
DataCloumn col=new DataCloumn();
DataRow row=table.NewRow();//建立行需要使用表的NewRow()方法
//為列指定資料類型
col.DataType=System.Type.GetType("System.Int32");
col.ColumnName="Hello";//定義列名屬性
//建立表間關系
使用DataRelation對象
DataRelation relation=new DataRelation(限制名,父表主鍵,子表主鍵);
//将這個關系再添加到子表中去
ds.Tables["子表名"].ParentRelations.Add(relation);
//擷取dataGridView對象中某單元格的值
dataGridView.CurrentRow.Cells[0].value
CurrentRow:目前行屬性
Cells:控件的列集合
//支援排序,篩選,搜尋的DataView類
DataView dv=ds.Tables["表名"].DefaultView;
//設定搜尋條件
dv.RowFilter="表中的列名="+條件值
//指定到資料源
dataGridView.DataSource=dv;
4. 關系與限制
5. 向DataSet中的表添加限制
比着老師的例子,完完整整的敲了一遍代碼,争取了解每一行代碼的含義,唯一搞不清楚的就是列屬性的ColumnName和Caption,百度了一下,說的也是不清不楚的,但最重要的是不影響建表和操作。
如果我把一個的字段屬性ColumnName="a", Caption="A",在測試中列标題顯示的是a. 如果說Caption這個屬性是給客戶看的,但是為啥列标題顯示的是表字段名呢?我試着設定row["A"]="test"時,提示是A是不是屬于表的屬性,就是隻能通過ColumnName屬性對表字段進行指派。一頭霧水!
原代碼如下:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Data.SqlClient;
namespace WF31
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
//資料庫連接配接字元串
string strConn = "server=.; database=hrms; uid=sa; pwd=123123;";
//資料檢索指令
string sqlSelect = "select bh,xm,xb,dz,bm from employee";
DataSet ds;//建立一個資料集對象引用
/// <summary>
/// 視窗加載
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Form1_Load(object sender, EventArgs e)
{
using (SqlConnection conn = new SqlConnection(strConn))
{
SqlCommand cmd = new SqlCommand(sqlSelect, conn);
cmd.CommandType = CommandType.Text;
SqlDataAdapter sda = new SqlDataAdapter();//建立一個資料擴充卡
ds = new DataSet();//建立一個資料集對象,預設資料集包含一個空表
sda.SelectCommand = cmd;//設定資料擴充卡的檢索指令對象的屬性
sda.Fill(ds);//使用資料擴充卡的Fill方填充資料到資料集的預設表中
//以下是綁定資料到DataGridView控件,隻能以表資料方式進行
//由于資料集中包含一個預設空表,且隻有一個表,在不知道表名的情況下,使用
//DataSet資料集的表集合中索引,如下
dataGridView1.DataSource = ds.Tables[0];//綁定資料表到控件
}
}
/// <summary>
/// 建立表
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button1_Click(object sender, EventArgs e)
{
DataTable table = new DataTable("Parent");//建立一個表對象,并初始化表名屬性
DataColumn column;//定義一個列引用
DataRow row;//定義一個行引用
column = new DataColumn();//建立一個表的列對象
//設定列的資料類型
column.DataType = System.Type.GetType("System.Int32");//第一列資料類型為整型
//設定列的名稱
column.ColumnName = "id";//這個名稱為字段名稱
//指定列的讀取方式
column.ReadOnly = true;//指定為隻讀
//列中的值是否為唯一值
column.Unique = true;
//設定列的标題
column.Caption = "ParentId";
//将此列添加到表的列集合中
table.Columns.Add(column);
//再建立一個列
column = new DataColumn();//初始化列對象
//設定列是否為自增列
column.ColumnName="item";
column.DataType=System.Type.GetType("System.String");
column.AutoIncrement = false;
column.Caption = "ParentItem";
column.ReadOnly = false;
column.Unique = false;
table.Columns.Add(column);
//設定表的主鍵,以集合的方式建立,意思就是可以通過此方式為表建立組合鍵
DataColumn[] PrimaryKeyColumns = new DataColumn[1];//隻包含一個主鍵列
//指定主鍵列
PrimaryKeyColumns[0] = table.Columns["id"];//指定字段id為此表的主鍵
//再将主鍵綁定到表中
table.PrimaryKey = PrimaryKeyColumns;
//為上表添加資料記錄,即行資料
//老師強調了,這個行記錄對象不能像列對象一個進行new DataRow;
//而是使用上面的已經執行個體化好了的Table架構進行執行個體化
row = table.NewRow();//使用現有的表架構來執行個體化行對象
//為建立的行對象中的每一列指派
row["id"] = 1;
row["item"] = "父表第一行資料";
//将生成的行添加到表的行集合
table.Rows.Add(row);
//再加一行
row = table.NewRow();
row["id"] = 2;
row["item"] = "父表第二行資料";
//将生成的行添加到表的行集合
table.Rows.Add(row);
//再加一行
row = table.NewRow();
row["id"] = 3;
row["item"] = "父表第三行資料";
//将生成的行添加到表的行集合
table.Rows.Add(row);
//建立一個資料集對象
ds = new DataSet();//初始化資料集對象
//将表添加到資料集的表集合中
ds.Tables.Add(table);
//************父子表的分隔線*********************
//接下來是建立一個子表
table = new DataTable("Child");
//初始化列對象
column = new DataColumn();
column.ColumnName = "id";
column.DataType = System.Type.GetType("System.Int32");
column.Caption = "ChildId";
column.AutoIncrement = true;
column.ReadOnly = true;
column.Unique = true;
table.Columns.Add(column);
column = new DataColumn();
column.ColumnName = "childItem";
column.Caption = "ChildItem";
column.DataType = System.Type.GetType("System.String");
column.AutoIncrement = false;
column.ReadOnly = false;
column.Unique = false;
table.Columns.Add(column);
//再組建一列作為主副間的關系列
column = new DataColumn();
column.ColumnName = "parentId";
column.Caption = "ParentId";
column.DataType = System.Type.GetType("System.Int32");
column.AutoIncrement = false;
column.ReadOnly = false;
column.Unique = false;
column.AllowDBNull = false;
table.Columns.Add(column);
//為子表添加資料
for (int i = 0; i < 5; i++)
{
row = table.NewRow();
row["childItem"] = "子表項資料第" + i + "号";
row["parentId"] = 1;
table.Rows.Add(row);
}
for (int i = 5; i < 11; i++)
{
row = table.NewRow();
row["childItem"] = "子表項資料第" + i + "号";
row["parentId"] = 2;
table.Rows.Add(row);
}
for (int i = 11; i < 15; i++)
{
row = table.NewRow();
row["childItem"] = "子表項資料第" + i + "号";
row["parentId"] = 3;
table.Rows.Add(row);
}
//也将此表添加到資料集中,因為在建立表的同時初始了表名屬性,可以以表名來指定表對象
ds.Tables.Add(table);
//最後是建立表間的關系
//先擷取父表的關系列
DataColumn PrimaryColumn = ds.Tables["Parent"].Columns["id"];
//擷取副表的關系列
DataColumn ChildColumn = ds.Tables["Child"].Columns["parentId"];
//建立表間關系
//關系類構造函數的三個參數:1.限制名,2.父表關系字段,3.子表關系字段
DataRelation relation = new DataRelation("PCrelation", PrimaryColumn, ChildColumn);
//将限制關系添加到子表中
ds.Tables["Child"].ParentRelations.Add(relation);//注意子表的父關系也是一個集合
if (ds.Tables.Count == 2)
{
MessageBox.Show("父表:" + ds.Tables["Parent"] + " 建立成功!\n子表:" + ds.Tables["Child"] + " 建立成功!");
}
else {
MessageBox.Show("建立失敗!");
}
}
/// <summary>
/// 綁定手工建立的表到控件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button2_Click(object sender, EventArgs e)
{
dgvParent.DataSource = ds.Tables["Parent"];
dgvChild.DataSource = ds.Tables["Child"];
}
private void dgvParent_CellClick(object sender, DataGridViewCellEventArgs e)
{
//先擷取使用者的選中行的主鍵
string pid = dgvParent.CurrentRow.Cells[0].Value.ToString();
//建立資料視圖對象
DataView dv = new DataView();
dv = ds.Tables["Child"].DefaultView;
dv.RowFilter = "parentId=" + Convert.ToInt32(pid);
dgvChild.DataSource = null;
dgvChild.DataSource = dv;
}
}
}
測試結果:(我的測試結果大多為gif小動畫,但有的去浏覽時不動,很大可能是伺服器被屏蔽,因為系統在沒有任何發動的情況下有時候是好的,可以另存為到本地看看。)