定义:
使用ADO.NET断开连接层,就会使用System.Data命名空间的许多成员(主要是DataTable、DataTable、DataRow、DataColumn、DataView和DataRelation)在调用层建模内存中的数据库数据。
当使用ADO.NET断开式访问方式的时候,不需要连接到数据库,但任然会使用拦截和命令对象。我们还会补充一个叫做数据适配器的特殊对象(扩展自DbDataAdapter抽象类)来获取和更新数据。
DataSet的作用
DataSet类型内部包含了3个强类型的集合。 DataTableCollection,DataRelationCollection,PropertyCollection.
DataSet的Table属性允许访问包含独立DataTable的DataTableCollection.而DataRelationCollection可以通过编程来表示各表之间的父子关系。(后面胡仔细介绍的)
ExtendedProperties属性提供了PropertyCollection对象的访问,通过它能把额外的名称/值信息关联到DataSet.
DataSet主要属性
方法:
构建DataSet ,一般我们的DataSet都是用来保存获取到的是数据,后面会就介绍到
只有在DataSet中插入几个DataTable时,DataSet对象才会有意思。我们先从DataColumn结构开始。
使用DataColumn
DataColumn类型表示DataTable中的一个单列,是DataTable中的结构。
构建DataColumn
启用自增列
使用DataRow
DataRow表示DataTable中的数据。
使用方法:
DataSate属性
当需要以编程方式指定表中的一组行被修改、新增等的时候。就会使用这个属性。是个枚举。
//创建一张表来做测试 DataTable temp = new DataTable("Temp"); temp.Columns.Add(new DataColumn("TempColumn", typeof(int))); DataRow row = temp.NewRow(); Console.WriteLine("添加行之前:{0}",row.RowState); temp.Rows.Add(row); Console.WriteLine("添加行:{0}", row.RowState); row["TempColumn"] = 11; Console.WriteLine("赋值:{0}",row.RowState); temp.AcceptChanges(); Console.WriteLine("提交更改:{0}",row.RowState); row["TempColumn"] = 10; Console.WriteLine("修改:{0}", row.RowState); temp.Rows[0].Delete(); Console.WriteLine("删除:{0}", row.RowState); Console.ReadLine();
使用DataTable
获取DataSet中的数据
一个完整的创建,填充,获取过程
DataTable dt = new DataTable(); DataColumn one = new DataColumn("One", Type.GetType("System.Int32")); DataColumn two = new DataColumn("Two", Type.GetType("System.String")); dt.Columns.AddRange(new DataColumn[] { one, two }); DataRow rowOne = dt.NewRow(); rowOne[0] = 1; rowOne[1] = "测试数据2"; DataRow rowTwo = dt.NewRow(); rowOne["One"] = 2; rowOne["Two"] = "好啊"; dt.Rows.Add(rowOne); dt.Rows.Add(rowTwo); DataSet ds = new DataSet("数据名称"); ds.Tables.Add(dt); //把表添加到DataSet中 ds.ExtendedProperties["TiemSpan"] = DateTime.Now; ds.ExtendedProperties["haha"] = "Hello"; Console.WriteLine("Set名称:{0}", ds.DataSetName); foreach (DataTable dt1 in ds.Tables) { foreach (System.Collections.DictionaryEntry item in ds.ExtendedProperties) { Console.WriteLine("Key={0}, Value={1}", item.Key, item.Value); } Console.WriteLine(); for (int i = 0; i < dt1.Columns.Count; i++) { Console.Write(dt1.Columns[i].ColumnName + " "); } Console.WriteLine(); for (int i = 0; i < dt1.Rows.Count; i++) { for (int j = 0; j < dt1.Columns.Count; j++) { Console.Write(dt1.Rows[i][j].ToString() + " "); } } }
使用DataTableReader对象处理 DataTable
DataTable支持一个叫做CreateDataReader()的方法,这个方法允许使用像数据读取器一样的方式(数据读取器会从内存DataTable而不是实际的数据库中读取数据,因此这里不涉及数据库连接)来获取DataTable内的数据。
DataTableReader dtReader = dt.CreateDataReader(); while (dtReader.Read()) { for (int i = 0; i < dtReader.FieldCount; i++) { Console.WriteLine("{0} ", dtReader.GetValue(i).ToString().Trim()); } Console.WriteLine(); } dtReader.Close();
序列化 DataTable/DataSet对象为XML
DataSet()和DataTable()都支持WriteXml()和ReadXml()方法。WiterXml()允许把它们的内容持久化成XML文档形式的本地文件(包括所有从System.IO.Stram继承的类型)。ReadXml()允许从XML文档加载数据到DataSet(或者DataTable).另外,DataSet和DataTable都支持WriteXmlSchema()和ReadXmlSchema()来保存和加载一个*.xsd文件。
例如:
//保存数据 ds.WriteXml("Test.xml"); ds.WriteXmlSchema("Demo.xsd"); //清除数据 ds.Clear(); //读取数据 ds.ReadXml("Test.xml");
XML格式:
XSD格式:
以二进制格式序列化DataTable/DataSet对象
还可以把DataSet(或单个DataTable)的内容以紧凑二进制格式进行持久化。如果DataSet对象需要跨越机器边界传递的话,这就特别有用。XML数据表现的一个劣势就是其强描述性可能会导致大量的负担。
我们只用设置 RemotingFormat属性为SerializationFormat.Binary.
//设置二进制序列化标记 Stsrem.Data ds.RemotingFormat = SerializationFormat.Binary; //以二进制格式保存DataSet FileStream fs = new FileStream("Binary.bin", FileMode.Create); //using System.Runtime.Serialization.Formatters.Binary; BinaryFormatter bFormat = new BinaryFormatter(); bFormat.Serialize(fs, ds); fs.Close(); ds.Clear(); //从二进制文件加载DataSset fs = new FileStream("Binary.bin", FileMode.Open); DataSet ds1 = (DataSet)bFormat.Deserialize(fs);
有关BinaryFormatter的操作,请查看 System.IO 二
从泛型List<T>合成DataTable
protected override void OnInit(EventArgs e) { //list集合 List<Car> listCar = new List<Car>() { new Car{ID=100, PetName="Chucky",Make="BMW",Color="Green"}, new Car{ID=101, PetName="Tiny",Make="Yugo",Color="white"}, new Car{ID=102, PetName="Ami",Make="Jeep",Color="Tan"}, new Car{ID=103, PetName="Pain",Make="Caravan",Color="Pink"}, new Car{ID=104, PetName="Fred",Make="BMW",Color="Green"}, new Car{ID=105, PetName="Sidd",Make="BMW",Color="Black"}, new Car{ID=106, PetName="Mel",Make="Firebird",Color="Red"}, new Car{ID=107, PetName="Sarah",Make="Colt",Color="Black"} }; DataTable dt = new DataTable(); //创建表结构 DataColumn IDColumn = new DataColumn("ID",typeof(int)); DataColumn PetNameColumn = new DataColumn("PetName",Type.GetType("System.String")); DataColumn MakeColumn = new DataColumn("Make",Type.GetType("System.String")); DataColumn ColorColumn = new DataColumn("Color",Type.GetType("System.String")); dt.Columns.AddRange(new DataColumn[] { IDColumn, PetNameColumn, MakeColumn, ColorColumn }); //添加行 foreach (Car item in listCar) { DataRow newRow = dt.NewRow(); newRow["ID"] = item.ID; newRow[1] = item.PetName; newRow["Make"] = item.Make; newRow["Color"] = item.Color; dt.Rows.Add(newRow); } //绑定数据 GridView1.DataSource = dt; GridView1.DataBind(); }
显示的数据:
//项目需要在4.5以上 异步才能使用,并且在页面上设置Async="true" protected async void Button1_Click(object sender, EventArgs e) { await Task.Run(() => { try { string id = TextBox1.Text; //查找需要删除的行 DataRow[] rowDelete = dt.Select(string.Format("ID={0}",int.Parse(id))); rowDelete[0].Delete(); //删除 dt.AcceptChanges();//提交更改 //重新绑定 GridView1.DataSource = dt; GridView1.DataBind(); } catch (Exception) { throw; } }); }
根据筛选条件选择行
//项目需要在4.5以上 异步才能使用,并且在页面上设置Async="true" protected async void Button2_Click(object sender, EventArgs e) { await Task.Run(() => { try { string name = TextBox2.Text; //过滤条件 //Select 第一个参数:条件,第二个参数:排序 DataRow[] makes = dt.Select(string.Format("Make='{0}'",name)); if (makes.Count()==0) { Page.ClientScript.RegisterStartupScript(Page.ClientScript.GetType(), "myScript", "<script>alert('没有找到合适的内容');</script>"); } else { string strMake = ""; for (int i = 0; i < makes.Length; i++) { strMake += makes[i]["PetName"] + ","; } Page.ClientScript.RegisterStartupScript(Page.ClientScript.GetType(), "myScript", "<script>alert('"+strMake+"');</script>"); } } catch (Exception) { throw; } }); }
在DataTable中更新行
修改是在找到行的基础上进行的,我们把上面的代码改下
使用DataView类型
视图对象是一个表(或一组表)自定义的表现形式。
使用数据适配器
一个简单的数据适配示例
string cnStr = @"server=Sealeesealee;uid=sa;pwd=a123;database=NewsDB;";//连接数据库 SqlDataAdapter dAdapt = new SqlDataAdapter("select * from News", cnStr); //查询数据 DataSet ds=new DataSet(); dAdapt.Fill(ds,"News");//填充DataSet
还可以使用强类型来操作DataSet,这里就不演示了。
LinQ to DataSet