相关知识:
- 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 ConsoleApplication10 10 { 11 class Program 12 { 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 try 60 { 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 }