相关知识:
- DataSet和DataAdapter的内部结构:
- DataSet通过DataAdapter从数据库中获取数据
- DataSet对象内部包括一个集合(Tables),也就是可以拥有多个表(DataTables);每个表存放着从数据库放回的一个结果集(一般由一条SELECT语句产生一个结果集)
- DataTable对象包含一个行集合(Rows),集合中的每个元素都是一个DataRow类型的对象。DataRow提供了通过下标或者列名进行访问字段数据的操作
- DataTable对象还包含一个列集合(Columns),集合中的每个元素都是一个DataColumn类型的对象,用于代表查询结果集合中每一列的属性,例如名称、数据类型等
- DataSet对象包含一个关联集合(Relations),集合中的每一个DataRelation代表两个表之间的关联。请注意,数据库表之间的关联不会被自动带到DataSet中来,需要变成为DataSet中的SataTable建立关联
- 可以由DataTable创建(DataView),DataView可以用来代表DataTable中经过过滤后的数据,并且将用来绑定到数据展现控件中
- 连接的打开和关闭
- 与SqlDataReader不用,使用DataAdapter对象,把数据加载到DataSet中,并不需要显式打开和关闭连接
- 当调用DataAdapter的Fill函数时,该函数内部首先检查连接对象是否已经打开
- 如果没有打开,则打开链接,填充数据,然后关闭连接
- 如果已经打开,则直接填充数据,之后也不关闭连接
- 一旦数据已经填充到DataSet中,就不必与数据库继续保持连接。事实上,DataSet中的数据全在内存中,与数据库无关。
代码示例:
(示例数据库使用红皮书的示例数据库:AdventureWorks_WroxSSRS2012)
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 using System.Data; 7 using System.Data.SqlClient; 8 9 namespace ConsoleApplication1010 {11 class Program12 {13 static void Main(string[] args)14 {15 string strConn = @"server=Joe-PC;database=AdventureWorks_WroxSSRS2012;uid=sa;pwd=root";16 SqlConnection conn = new SqlConnection(strConn);17 18 DataSet ds = new DataSet();19 20 string strCmd1 = "SELECT ProductCategoryID,Name FROM Production.ProductCategory";21 SqlDataAdapter da1 = new SqlDataAdapter(strCmd1, conn);22 // 将第一个查询结果集合填入DataSet中,并且将DataTable命名为"Category"23 da1.Fill(ds, "Category");24 25 string strCmd2 = "SELECT ProductSubcategoryID,ProductCategoryID,Name From Production.ProductSubcategory";26 SqlDataAdapter da2 = new SqlDataAdapter(strCmd2, conn);27 // 将第二个查询结果集合填入DataSet中,并且将DataTable命名为"Subategory"28 da2.Fill(ds, "Subcategory");29 30 // 使用视图31 // 打印表中的数据32 Console.WriteLine("主类别表:");33 DataTable dt1 = ds.Tables["Category"];//获得Category表34 DataView dv1 = new DataView(dt1); //创建视图35 dv1.Sort = "ProductCategoryID ASC"; //设置排序规则36 foreach (DataRowView drv in dv1)37 {38 Console.WriteLine("{0}:{1}", drv[0], drv["Name"]);39 }40 41 Console.WriteLine("");42 43 Console.WriteLine("过滤后的子类别表:");44 DataTable dt2 = ds.Tables["Subcategory"];45 DataView dv2 = new DataView(dt2);46 dv2.RowFilter = "ProductSubcategoryID>10";//设置过滤条件47 dv2.Sort = "ProductSubcategoryID ASC";48 foreach (DataRowView drv in dv2)49 {50 Console.WriteLine("{0}:{1}", drv[0], drv["Name"]);51 }52 53 Console.WriteLine("");54 55 // 在两个表之间建立关联56 DataRelation relation = new DataRelation("ProductCategory_ProductSubcategory",57 dt1.Columns["ProductCategoryID"], dt2.Columns["ProductCategoryID"]);58 ds.Relations.Add(relation);//将关联添加到DataSet的集合中59 try60 {61 for (int i = 0; i < dt1.Rows.Count; i++)62 {63 DataRow dri = dt1.Rows[i];64 //根据关联找到数据相关的子类别数据65 DataRow[] subRows = dri.GetChildRows(relation);66 Console.WriteLine("{0}的子类别信息:", dri["Name"]);67 foreach (DataRow dr in subRows)68 {69 Console.WriteLine("{0}:{1}", dr[0], dr["Name"]);70 }71 Console.WriteLine("");72 }73 }74 catch (Exception e)75 {76 Console.WriteLine(e);77 }78 }79 }80 }