DataSet
对象就像存放于内存中的一个小型数据库。它可以包含数据表、数据列、数据行、视图、约束以及关系。
DataSet
数据通常来源于数据库或XML,为了从数据库中获取数据,需要使用数据适配器 DataAdapter
从数据库中查询数据。
//创建DataSet
DataSet ds = new DataSet("DataSetDemo");
//创建表1:Student
DataTable dt1 = new DataTable("Student");
//表Student中创建列
dt1.Columns.Add("学号", typeof(string));
dt1.Columns.Add("姓名", typeof(string));
dt1.Columns.Add("性别", typeof(string));
dt1.Columns.Add("年龄", typeof(Int16));
dt1.Columns.Add("爱好", typeof(string));
//表Student中添加一行
DataRow dr1 = dt1.NewRow();
dr1["学号"] = "1001";
dr1["姓名"] = "小羽";
dr1["性别"] = "男";
dr1["年龄"] = 9;
dr1["爱好"] = "跑步";
dt1.Rows.Add(dr1);
//创建表2:Score
DataTable dt2 = new DataTable("Score");
//表Score中创建列
dt2.Columns.Add("学号", typeof(string));
dt2.Columns.Add("科目", typeof(string));
dt2.Columns.Add("成绩", typeof(Decimal));
//表Score中添加一行
DataRow dr2 = dt2.NewRow();
dr2["学号"] = "1001";
dr2["科目"] = "语文";
dr2["成绩"] = "95";
dt2.Rows.Add(dr2);
//将Student表和Score表添加到DataSet中
ds.Tables.Add(dt1);
ds.Tables.Add(dt2);
Relations
:获取用于将表链接起来并允许从父表浏览到子表的关系的集合。 //最后一个参数表示是否创建约束。当参数为true且清空建立关系的DataTable数据时,需要先将DataSet的EnforceConstraints设置为false
ds.Relations.Add("成绩", dt1.Columns["学号"], dt2.Columns["学号"], false);
Tables
:获取包含在 DataSet
中的表的集合。 string strTableNames = "";
foreach (DataTable dt in ds.Tables) { strTableNames += dt.TableName + " "; }
ExtendedProperties
:获取或设置用户自定义信息的集合。 ds.ExtendedProperties["AvgAge"] = ds.Tables[0].Compute("avg(年龄)", "True");
AcceptChanges
:提交自加载此 DataSet
或上次调用 AcceptChanges
以来对其进行的所有修改。 ds.AcceptChanges();
Clear
:清除所有表的行数据。 ds.Clear();
Clone
:复制该 DataSet
的结构。 DataSet ds1 = ds.Clone();
Copy
:复制该 DataSet
的结构和数据。 DataSet ds1 = ds.Copy();
HasChanges
:获取一个值,该值指示 DataSet
是否有更改,包括新增行、已删除的行或已修改的行。 bool isChange = ds.HasChanges()
GetChanges
:获取 DataSet
的副本,该副本包含自加载以来或自上次调用 AcceptChanges
以来对该数据集进行的所有更改。 DataSet ds1 = ds.GetChanges();
ds1 = ds.GetChanges(DataRowState.Modified); //带筛选条件
Merge
:将指定对象合并到 DataSet
中。 //合并DataRow
DataSet ds1 = ds.Clone();
DataRow[] drs = ds.Tables[0].Select("性别='男'");
ds1.Merge(drs);
//合并DataTable
DataTable dt1 = ds.Tables[0].Clone();
dt1.Columns.Add("班级", typeof(string));
DataRow dr = dt1.NewRow();
dr["学号"] = "5005";
dr["姓名"] = "小飞";
dr["性别"] = "男";
dr["年龄"] = 9;
dr["爱好"] = "跑步";
dr["班级"] = "一班";
dt1.Rows.Add(dr);
ds.Merge(dt1, true, MissingSchemaAction.Add);
//合并DataSet
DataSet ds1 = ds.Copy();
ds.Merge(ds1);
DataTable
类型定义了许多成员,许多在名称和功能上和 DataSet
差不多。一个 DataSet
可能包含多个 DataTable
。
//要实例化一个DataRow对象不能使用new DataRow(),应该使用DataTable.NewRow()
DataSet ds = new DataSet("DataSetDemo");
DataTable dt = new DataTable("Student");
dt.Columns.Add("学号", typeof(string));
dt.Columns.Add("姓名", typeof(string));
dt.Columns.Add("性别", typeof(string));
dt.Columns.Add("年龄", typeof(Int16));
dt.Columns.Add("爱好", typeof(string));
dt.Rows.Add("1001","小羽","男",9,"跑步");
DataRow dr = dt.NewRow();
dr["学号"] = "2002";
dr["姓名"] = "小丽";
dr["性别"] = "女";
dr["年龄"] = 6;
dr["爱好"] = "音乐";
dt.Rows.Add(dr);
ds.Tables.Add(dt);
Columns
:获取属于该表的列的集合。 string strColumns = "";
foreach (DataColumn dc in dt.Columns) { strColumns += dc.ColumnName + " "; }
MessageBox.Show("学生表中共有 " + dt.Columns.Count.ToString() + " 列,分别为:\n\n" + strColumns);
DataSet
:获取此表所属的 DataSet
。 MessageBox.Show("学生表所属的 DataSet 名为:" + dt.DataSet.DataSetName);
DefaultView
:获取表的自定义视图。 MessageBox.Show("点击“确定”将按年龄升序排序");
DataTable dt = wnGrid.DataSource;
dt.DefaultView.Sort = "年龄 asc";
PrimaryKey
:获取或设置数据表主键的列的数组。 dt.PrimaryKey = new DataColumn[] { dt.Columns["学号"] };
Rows
:获取属于该表的行的集合。 MessageBox.Show("学生表中共有 " + dt.Rows.Count.ToString() + " 条记录");
TableName
:获取或设置 DataTable
的名称。 MessageBox.Show("学生表的 TableName 为:" + dt.TableName);
ExtendedProperties
:获取或设置用户自定义信息的集合。 //ExtendedProperties扩展属性是PropertyCollection类型(Hashtable:<object,object>键值对),故可以存放任何类型的数据
dt.ExtendedProperties["RowIndex"] = dt.Rows.Count == 0 ? -1 : 0;
AcceptChanges
:提交自加载以来或自上次调用 AcceptChanges
以来对该表进行的所有更改。 dt.AcceptChanges();
Clear
:清除所有行数据。 dt.Clear();
Clone
:复制 DataTable
的结构。 DataTable dtClone = dt.Clone();
Copy
:复制 DataTable
的结构和数据。 DataTable dt1 = dt.Copy();
Compute
:在符合过滤条件的行上执行给定表达式的计算,并返回计算结果。 MessageBox.Show("计算学生的总年龄:\n\n公式:sum(年龄)\n\n过滤:1=1\n\n结果:" + dt.Compute("sum(年龄)", "1=1").ToString());
GetChanges
:获取 DataTable
的副本,该副本包含自加载以来或自上次调用 AcceptChanges
以来对该数据集进行的所有更改。 DataTable dt1 = dt.GetChanges();
dt1 = dt.GetChanges(DataRowState.Modified); //带筛选条件
ImportRow
:将 DataRow
复制到 DataTable
中,保留原属性设置、初始值、当前值,以及行状态。 DataTable dt1 = dt.Clone();
dt1.ImportRow(dt.Rows[0]);
NewRow
:创建与该表具有相同架构的 DataRow
对象。 DataRow dr = dt.NewRow();
dr["学号"] = "5005";
dr["姓名"] = "小小";
dr["性别"] = "男";
dr["年龄"] = 8;
dr["爱好"] = "游泳";
dt.Rows.Add(dr);
Select
:获取符合筛选条件的所有 DataRow
对象的数组。 DataRow[] rows = dt.Select("年龄<9");
foreach (DataRow row in rows)
{
strInfo += row["姓名"].ToString() + ":" + row["年龄"].ToString() + " 岁\n\n";
}
MessageBox.Show("通过 Select(参数) 方法\n\n按“年龄<9”过滤:\n\n" + strInfo);
DataColumn
类型表示 DataTable
的一个单列。一般来说,一组 DataColumn
类型绑定到一个特定的 DataTable
,组合成一个表的基本结构信息。
//构建DataColumn时,常用的数据类型有:String、DateTime、Decimal、Int32、Boolean、Char
DataTable dt = new DataTable("Product");
//添加DataColumn
DataColumn spmc = new DataColumn("Spmc", typeof(String));
spmc.Caption = "商品名称";
DataColumn dj = new DataColumn("Dj", typeof(Int32));
dj.Caption = "单价";
DataColumn sl = new DataColumn("Sl", typeof(Int32));
sl.Caption = "数量";
DataColumn zj = new DataColumn("Zj", typeof(Int32));
zj.Caption = "总价";
dt.Columns.Add(spmc);
dt.Columns.Add(dj);
dt.Columns.Add(sl);
dt.Columns.Add(zj);
//添加DataRow
DataRow dr1 = dt.NewRow();
dr1["Spmc"] = "足球";
dr1["Dj"] = 50;
dr1["Sl"] = 11;
dr1["Zj"] = 550;
dt.Rows.Add(dr1);
DataRow dr2 = dt.NewRow();
dr2["Spmc"] = "蓝球";
dr2["Dj"] = 10;
dr2["Sl"] = 11;
dr2["Zj"] = 110;
dt.Rows.Add(dr2);
Caption
:获取或设置列的标题;如果没有设置,则为 ColumnName
的值。 foreach (DataColumn dc in dt.Columns)
{
MessageBox.Show(dc.ColumnName + "的[Caption]为:" + dc.Caption);
}
ColumnName
:获取或设置列的名称。 foreach (DataColumn dc in dt.Columns)
{
MessageBox.Show(dc.Caption + "对应的[ColumnName]为:" + dc.ColumnName);
}
DataType
:获取或设置列的数据类型。 foreach (DataColumn dc in dt.Columns)
{
MessageBox.Show(dc.ColumnName + "对应的[DataType]为:" + dc.DataType.ToString());
}
DefaultValue
:获取或设置列的默认值。 dt.Columns["Dj"].DefaultValue = 15;
MaxLength
:获取或设置文本列的最大长度。 dt.Columns["Spmc"].MaxLength = 3;
Ordinal
:获取列在 DataColumnCollection
集合中的位置。 foreach (DataColumn dc in dt.Columns)
{
MessageBox.Show(dc.ColumnName + "的[Ordinal]为:" + dc.Ordinal);
}
Table
:获取列所属 DataTable
。 dt.Columns["Spmc"].Table.TableName
ExtendedProperties
:获取或设置用户自定义信息的集合。 public class Product
{
public string spmc;
public int sl;
public int dj;
public int zj;
public Product(string spmc, int sl, int dj, int zj)
{
this.spmc = spmc;
this.sl = sl;
this.dj = dj;
this.zj = zj;
}
}
//设置属性值
Product product1 = new Product("篮球", 1, 30, 30);
dt.Columns[0].ExtendedProperties["Spmc"] = product1;
//获取属性值
Product product2 = dt.Columns[0].ExtendedProperties["Spmc"] as Product;
MessageBox.Show("商品名称:" + product2.spmc + " 单价:" + product2.dj);
SetOrdinal
:将列的序号或位置更改为指定的序号或位置。 MessageBox.Show("将[总价]的位置移至第一列");
dt.Columns["Zj"].SetOrdinal(0);
DataColumn
对象的集合用来表示 DataTable
的结构,而 DataRow
对象的集合表示的是表中的实际数据。
DataTable dt = new DataTable("Student");
//添加列
dt.Columns.Add("学号", typeof(string));
dt.Columns.Add("姓名", typeof(string));
dt.Columns.Add("年龄", typeof(Int32));
//添加行
dt.Rows.Add("001", "张三", 21);
dt.Rows.Add("002", "李四", 22);
dt.Rows.Add("003", "王五", null);
ItemArray
:获取或设置存储在此行的所有值。 DataRow dr = dt.Rows[0];
MessageBox.Show("ItemArray属性得到的行数据的值为:" + dr.ItemArray[0] + "," + dr.ItemArray[1]);
RowState
:获取该行的当前状态,共有5种状态,分别是:Detached
、Added
、Unchanged
、Modified
、Deleted
。 MessageBox.Show("演示从新增一行到删除此行过程中不同的行状态");
//Deteched状态
DataRow dr = dt.NewRow();
MessageBox.Show("调用NewRow()方法后行状态为:" + dr.RowState.ToString());
//Added状态
dr["学号"] = "005";
dr["姓名"] = "赵六";
dr["年龄"] = 23;
dt.Rows.Add(dr);
MessageBox.Show("调用Add()方法后行状态为:" + dr.RowState.ToString());
//Unchanged状态
dr.AcceptChanges(); //提交对dr的更改,如果不提交,在Added状态下修改此行,其状态仍为Added状态而不是Modified状态
MessageBox.Show("调用AcceptChanges()方法后行状态为:" + dr.RowState.ToString());
//Modified状态
dr["姓名"] = "赵六1";
MessageBox.Show("修改此行内容后行状态为:" + dr.RowState.ToString());
//Deleted状态
dr.Delete();
MessageBox.Show("调用Delete()方法后行状态为:" + dr.RowState.ToString());
//Deteched状态
dr.AcceptChanges();
MessageBox.Show("调用AcceptChanges()方法后行状态为:" + dr.RowState.ToString());
Table
:获取该行所属 DataTable
。 MessageBox.Show("第一行DataRow对应的DataTable.TableName为:" + dt.Rows[0].Table.TableName);
AcceptChanges
:提交上次调用 AcceptChanges
以来对该行的所有更改。 DataRow dr = dt.Rows[0];
dr.AcceptChanges();
注意:
当
DataRow
状态为Added
和Modified
时,调用AcceptChanges()
方法状态变为Unchanged
状态; 当DataRow
状态为Deleted
时,调用AcceptChanges()
方法状态变为Detached
状态。
Delete
:删除 DataRow
对象。 DataRow dr = dt.Rows[0];
dr.Delete();
IsNull
:判断指定的 DataColumn
是否为空值。 DataRow dr = dt.Rows[0];
dr.IsNull("姓名")
SetAdded
:将 DataRow
对象的 RowState
更改为Added。 //用SetAdded()方法循环将dt中的行设置为Added状态
for (int i = 0; i < dt.Rows.Count; i++)
{
dt.Rows[i].SetAdded();
}
MessageBox.Show("调用SetAdded()方法后的行状态为:\n\n" + dt.Rows[0].RowState + "," + dt.Rows[1].RowState + "," + dt.Rows[2].RowState);
SetModified
:将 DataRow
对象的 RowState
更改为 Modified
。 //用SetModified()方法循环将dt中的行设置为Modified状态
for (int i = 0; i < dt.Rows.Count; i++)
{
dt.Rows[i].SetModified();
}
MessageBox.Show("调用SetModified()方法后的行状态为:\n\n" + dt.Rows[0].RowState + "," + dt.Rows[1].RowState + "," + dt.Rows[2].RowState);
扩展:
不同行状态的
DataRow
具有不同的行版本,行版本的类型有Original(原始值)
、Current(当前值)
、ProPosed(建议值)
和Default(默认值)
。不同行状态
DataRow
所具有的行版本:
Detached
:行版本有ProPosed
和Default
,其中Default值为ProPosed
Added
:行版本有Current
和Default
,其中Default值为Current
Unchanged
:行版本有Original
、Current
和Default
,其中Default值为Current
Modified
:行版本有Original
、Current
和Default
,其中Default值为Current
Deleted
:行版本有Original
和Default
,其中Default值为Original
数据视图。DataView
可以用于对 DataTable
筛选,搜索,排序,编辑和导航。可以方便对 DataTable
的操作。
DataTable dt = new DataTable("商品表");
DataColumn dc = dt.Columns.Add("商品编码", typeof(Int32));
dc.ReadOnly = true;
dc.AutoIncrement = true;
dc.AutoIncrementSeed = 1;
dt.Columns.Add("商品名称", typeof(string));
dt.Columns.Add("商品价格", typeof(int));
dt.Columns.Add("商品产地", typeof(string));
dt.Columns.Add("商品生产商", typeof(string));
DataRow dr = dt.NewRow();
dr["商品名称"] = "足球";
dr["商品价格"] = 99;
dr["商品产地"] = "山东";
dr["商品生产商"] = "鲁泰";
dt.Rows.Add(dr);
DataRow dr1 = dt.NewRow();
dr1["商品名称"] = "足球";
dr1["商品价格"] = 88;
dr1["商品产地"] = "山东";
dr1["商品生产商"] = "鲁泰";
dt.Rows.Add(dr1);
dt.AcceptChanges();
//获取DataView视图
DataView dv = dt.DefaultView;
Count
:获取 DataView
中记录的个数。 int count = dv.Count
RowFilter
:获取或设置 DataView
的条件过滤表达式。 dv.RowFilter = "商品名称 like '%足球%'"
RowStateFilter
:获取或设置 DataView
的行状态过滤表达式。
Added
:新添加的行
CurrentRows
:包括未更新的,新的和已修改的当前行
Deleted
:已删除的行
ModifiedOriginal
:已修改的数据的原始版本
ModifiedCurrent
:已修改的原始数据的当前版本
None
:无
OriginalRows
:包括未更改行和已删除行的原始数据
Unchanged
:未更改的行
MessageBox.Show("将第一行[商品产地]列的值修改为“江苏”");
dt.Rows[0]["商品产地"] = "江苏";
dv.RowStateFilter = DataViewRowState.ModifiedOriginal;
MessageBox.Show("第一行[商品产地]列修改前的值是“" + dv[0]["商品产地"] + "”");
dv.RowStateFilter = DataViewRowState.ModifiedCurrent;
MessageBox.Show("第一行[商品产地]列修改后的值是“" + dv[0]["商品产地"] + "”");
Sort
:获取或设置 DataView
的排序表达式。 MessageBox.Show("按[商品名称]降序,[商品价格]升序排序");
dv.Sort = "商品名称 desc,商品价格 asc";
Table
:获取或设置源 DataTable
。 MessageBox.Show("当前DataView对应的Table.TableName是:" + dv.Table.TableName)
Find
:按指定的排序关键字值在 DataView
中查找,返回符合条件的第一行的索引。 MessageBox.Show("将 Sort 属性设为“商品名称,商品价格”,\n\n然后调用 Find(object[]) 方法");
dv.Sort = "商品名称,商品价格";
index = dv.Find(new object[] { "足球", "99" });
if (index == -1)
{
MessageBox.Show("没有找到[商品名称]是“足球”且[商品价格]是“99”的记录");
}
else
{
MessageBox.Show("[商品名称]是“足球”且[商品价格]是“99”的\n\n第一条记录的索引值是: " + index);
}
FindRows
:按指定的排序关键字值在 DataView
中查找,返回所有符合条件的 DataRowView
对象的数组。 MessageBox.Show("先将 Sort 属性设为“商品名称”,\n\n然后调用 FindRows(object) 方法");
dv.Sort = "商品名称";
DataRowView[] drv = dv.FindRows("足球");
MessageBox.Show("[商品名称]是“足球”的记录数为:" + drv.Length);
ToTable
:根据现有 DataView
中的行,创建并返回一个新的 DataTable
。 DataTable dt = dv.ToTable("商品表_New", true, "商品名称", "商品产地");
MessageBox.Show("调用 ToTable(string tableName, bool distinct, params string[] columnNames) 方法得到的\n\n新表名称是:" + dt.TableName);