07.memoryobject.md 19 KB

内存对象

一、DataSet对象

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对象

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对象

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);

四、DataRow对象

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种状态,分别是:DetachedAddedUnchangedModifiedDeleted
  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 状态为 AddedModified 时,调用 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);

扩展:

  1. 不同行状态的 DataRow 具有不同的行版本,行版本的类型有 Original(原始值)Current(当前值)ProPosed(建议值)Default(默认值)

  2. 不同行状态 DataRow 所具有的行版本:

Detached:行版本有 ProPosedDefault ,其中Default值为 ProPosed

Added:行版本有 CurrentDefault ,其中Default值为 Current

Unchanged:行版本有 OriginalCurrentDefault,其中Default值为 Current

Modified:行版本有 OriginalCurrentDefault,其中Default值为Current

Deleted:行版本有 OriginalDefault,其中Default值为 Original

五、DataView对象

数据视图。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);