DataSet与DataTable对象

摘自:http://www.cnblogs.com/fttbfttb/articles/1509662.html

DataSet对象

DataSet是ADO.NET中最核心的成员之一,是各种基于.NET平台程序语言(如VB.NET、C#.NET、C++.NET)的数据库应用程序开发最常接触的类,这是因为DataSet在ADO.NET实现从数据库中抽取数据的作用。数据抽取后,DataSet就是数据的存放地,它是各种数据源(SQL Server 、OLE DB等)的数据在计算机内存的缓存,所以有时说DataSet可以看成是一个数据容器(又称数据集)。在客户端通过对DataSet的数据集读取、更新等操作,从而实现对数据源的同等操作。

DataSet的最大优点是离线(断开)和连接。DataSet既可以以离线方式,也可以以实时连接方式来操作数据库中的数据。这样的好处是大大减少了服务器端数据库的连接线程,从而大大地减少了服务器端的运行压力。所以,在数据量不大的情况下,使用DataSet是最好的选择。

DataSet的基本工作过程:应用程序一般并不直接对数据库进行操作(直接在程序中调用存储过程等除外),而是先完成和数据库的连接,接着通过数据适配器(DataAdapter)把数据库中的数据填入DataSet对象,然后客户端再通过读取DataSet来获得需要的数据,同样,在更新数据库中的数据时,也是首先更新DataSet,然后再通过DataSet和数据适配器将更新的数据同步地解释入数据库中。

DataSet中的几个重要对象:
TablesCollection对象:DataSet 里的表用DataTable来表示,一个DataSet里面可以包含多个DataTable,这些DataTable就构成了 TablesCollection对象。每个DataTable中都包含一个ColumnsColleciton和一个RowsCollection对 象。
RelationsCollection对象:各个DataTable之间的关系通过DataRelation来表达,这些DataRelation构成的集合就是RelationsCollection对象。
ExtendedProperties对象:这个对象用来定义特定的信息,比如密码、更新时间等。

DataTable对象

每一个DataSet都是一个或多个DataTable 对象的集合(DataTable相当于数据库中的表),这些对象由数据行(DataRow)、数据列(DataColumn)、字段名(Column Name)、数据格(Item),以及约束(Constraint)和有关DataTable对象中数据的关系(Relations)与数据显示排序(DataView)信息组成。

DataView用来在观察数据时提供排序和过滤的功能。DataColumn用来对表中的数据值进行一定的规限。比如哪一列数据的默认值是什么、哪一列数据值的范围是什么、哪个是主键、数据值是否是只读等。

由于一个DataSet可能存在多张表,这些表可能存在关联关系,因此用parentRelations和childRelations来表述。ParentRelations表是父表,childRelations是子表,子表是对父表的引用,这样就使得一个表中的某行与另一个表中的某一行甚至整个表相关联。

1.DataSet操作

①用DataAdapter填充

DataSetDataSet ds = new DataSet();

adapter.Fill(ds);

adapter.Fill(ds, "表名"); //用一个表去填充DataSet.

②合并两个DataSet

myConnection.Open();

string strSQL = "SELECT * FROM P_Product";

DataSet ds1 = new DataSet();

SqlDataAdapter adapter1 = new SqlDataAdapter(strSQL, myConnection);

adapter1.Fill(ds1, "Product");

strSQL = "SELECT * FROM P_Category";

DataSet ds2 = new DataSet();

SqlDataAdapter adapter2 = new SqlDataAdapter(strSQL, myConnection);

adapter2.Fill(ds2, "Category");

myConnection.Close();

//ds1就是合并后的DataSet

ds1.Merge(ds2, true, MissingSchemaAction.AddWithKey);

GridView1.DataSource = ds1.Tables["Product"];

GridView1.DataBind();

GridView2.DataSource = ds1.Tables["Category"];

GridView2.DataBind();

2.DataTableCollection操作

表示 DataSet 的表的集合。

DataTableCollection dtc = ds.Tables;

DataTable customerTable = dtc["Product"];

3.DataRelation操作

//创建DataRelation
DataRelation dr;
DataColumn parentCol;
DataColumn childCol;

parentCol = ds.Tables["Customers"].Columns["CustomerID"];
childCol = ds.Tables["Orders"].Columns.["CustomerID"];
dr = new DataRelation("CustOrders", parentCol, childCol);
ds.Relations.Add(dr);

currentParentRow = ds.Tables["Customers"].Rows[DataGridName.SelectedIndex];
foreach(DataRow r in currentParentRow.GetChildRow("CustOrders"))
{
   Lable1.Text += r["OrderID"] + ",";
}

//DataRelation实现父子表(范例)

if (!IsPostBack)
{
    using (OleDbConnection con = new OleDbConnection(cn))
    {
          DataSet ds = new DataSet();

OleDbDataAdapter dr1 = new OleDbDataAdapter("select * from km", con);
          OleDbDataAdapter dr2 = new OleDbDataAdapter("select * from km1", con);
          dr1.Fill(ds, "tb1");
          dr2.Fill(ds, "tb2");

ds.Relations.Add("newtb", ds.Tables[0].Columns["id"], ds.Tables[1].Columns["flag"]);
          Repeater1.DataSource = ds;
          Repeater1.DataBind();

}
}

<asp:Repeater ID="Repeater1" runat="server">
<ItemTemplate>
<div class="adminleft" id='admin<%# Eval("id") %>'>
<h2 id='h<%# Eval("id") %>' onmouseout="fff('h<%# Eval("id") %>')" onmouseover="f('h<%# Eval("id") %>')" onclick="javascript:location.href='showbj.aspx?flag=<%# Eval("id") %>&na=<%# Eval("subject") %>'"><%#Eval("subject") %></h2>
     <ul>
     <asp:Repeater ID="Repeater2" runat="server" DataSource='<%# ((DataRowView)Container.DataItem).Row.GetChildRows("newtb") %>' OnItemCommand="Repeater1_ItemCommand">
     <ItemTemplate>
     <li><asp:LinkButton ID="LinkButton1" runat="server" CommandArgument='<%#Eval("[\"flag\"]") %>' CommandName="re"><%#Eval("[\"subject\"]") %></asp:LinkButton></li>
     </ItemTemplate>
     </asp:Repeater>
     </ul>
</div>
</ItemTemplate>
</asp:Repeater>

4.DataTable操作

①创建一个DataTable

DataTable MyTable;
MyTable = new DataTable ("Test");
MyTable.CaseSensitive = False;//是否区分大小写
MyTable.MinimumCapacity = 100;//数据库的最小记录空间

②创建表列

DataTable MyTable;
DataColumn MyColumn;
MyTable = new DataTable ("表名");

MyColumn = MyTable.Columns.Add("列名",typeof(string));

MyColumn = MyTable.Columns.Add("列名",typeof(int));

③创建表达式列

//方法一
DataColumn tax = new DataColumn();
tax.DataType = typeof(Currency);
tax.Expression = "total*rate*0.20";

//方法二
MyTable.Columns.Add("tax", typeof(Currency), "total*rate*0.20");

④从DataTable中删除DataRow对象

(1)DataRowCollection对象的Remove方法

DataRow drEmployee = dtEmployees.Rows(3);
     dtEmployees.Rows.Remove(drEmployee);

(2)DataRow对象的Delete方法

drEmployee.Delete;

比较:Remove方法时从DataRowCollection中删除DataRow,而Dalete方法只是对删除的行做标记。
DataRow类包括RowState属性。RowState属性值表示从第一次创建DataTable(或从数据库加载DataTable)开始,行是 否发生更改,如何更改以及通过何种方式更改。属性的可选值:Modified | Detached | Added。

⑤DataTable进行动态的筛选和排序

(1)获取所有行。

  1. DataRow[] rows = dt.Select();

(2)按主键顺序(如没有主键,则按照添加顺序)获取符合筛选条件的行。

  • DataRow[] rows = dt.Select("ID>52");

(3)获取符合筛选条件的行,并按指定的排序条件排序。

  • DataRow[] rows = dt.Select("ID>52","ID DESC");

(4)获取符合筛选条件和指定状态的行,并按指定的排序条件排序。

  1. string strExpr = "ID>52";
  2. string strSort = "ID DESC";
  3. DataRow[] foundRows = dt.Select(strExpr, strSort, 
    DataViewRowState.OriginalRows);

⑥DataTable进行数据统计

我们在使用SQL Server时,可以轻松地对数据进行Sum、Aver、Count等操作以获得统计结果,那么,在已经把数据检索出来的DataSet(DataTable)中如何进行统计呢?特别是通过第三方接口Web Service获得了DataSet,这个时候,没有办法去执行Select语句来获取这些统计,怎么办呢?

办法总比问题多,其实在DataTable中也是可以进行数据统计的。

下面就通过几个简单的示例,介绍一下如何无须通过逐条记录进行计算就可以轻松地获得DataTable中的记录统计结果。这里调用的是功能强大的DataTable的函数Compute。

(1)函数说明:

  1. public object Compute(string strExpression,string strFilter);

strExpression:要计算的表达式字符串,基本上类似于Sql Server中的统计表达式。

strFilter:统计的过滤字符串,只有满足这个过滤条件的记录才会被统计。

(2)调用示例。

假设一个产品销售表P_Sell,描述商场中各销售人员的销售记录,如表5-2所示。

表5-2  产品销售表

序号

列名

数据类型

长度

主键

允许空

说明

1

ID

int

4

流水号

2

Name

varchar

50

姓名

3

Sex

smallint

2

性别:0为女,1为男

4

Birthday

datetime

8

生日

5

ProductId

varchar

20

销售产品代码

6

Num

int

4

销售的数量

7

Price

decimal

9

销售价格

统计所有性别为女的销售员的数量:

  1. object n = table.Compute("count(ID)", "Sex = 0");

统计所有年龄大于20岁的销售员的数量:

  1. int c=(int)table.Compute("count(ID)",
  2. "Birthday<'" + DateTime.Today.AddYears(-20)+"'");

统计销售产品的平均价格:

  1. decimal ap=(decimal)table.Compute("avg(Price)", "true");

统计产品代码为1的产品销售数量:

  1. object m = table.Compute("sum(Num)", "ProductId='sj'");

统计所有产品的销售总金额:要统计销售总金额,table中不存在某项产品某个促销员销售的金额数据,但我们可以通过Quantity*Price来获得。比如table.Compute("Sum(Quantity*Price)","true");。

这里有一个问题是,DataTable的统计功能没有SqlServer强大,这个写法是错误的! 因为Compute的统计不具备Sum(Quantity*Price)这样的数据的功能。那怎么办呢?

对于这样复杂数据的统计,我们可以通过在DataTable中创建一个新的DataColumn来完成,比如为"total",同时设置该字段的Expression为Quantity*Price,这样我们就可以使用统计功能了。

  1. DataColumn dc = new DataColumn("total", Type.GetType("System.Decimal"));
  2. dc.Expression = "Num*Price";
  3. table.Columns.Add(dc);
  4. object s=table.Compute("sum(total)", "true");

当然,这个功能也可以通过 DataGrid增加一个模板列,在ItemDataBind事件里实现计算。

⑦.合并两个DataTable表的数据

  1. DataTable dt1 = ds.Tables[0];
  2. DataTable dt2 = ds.Tables[1];
  3. dt1.Merge(dt2, true, MissingSchemaAction.AddWithKey);

5.DataView操作

DataView就时数据视图,为数据库结构提供了外模式的实现。同时DataView也可以为窗体控件和Web控件提供数据绑定功能,在每一个DataTable中内建了一个DataView为:DataTable.DefaultView()。

(1)得到DataView。

  1. DataView dv = ds.Tables[0].DefaultView;
  2. //或
  3. DataView dv = new DataView(ds.Tables["Product"], "ID > 52", "ID DESC",
  4. DataViewRowState.CurrentRows);

(2)得到DataView的行数据。

  1. foreach (DataRowView rowview in dv)
  2. {
  3. for (int i = 0; i < dv.Table.Columns.Count; i++)
  4. {
  5. Response.Write(rowview[i] + "
    ");
  6. }
  7. }

(3)对结果集过滤排序。

  1. DataView dv = ds.Tables[0].DefaultView;
  2. dv.RowFilter = "ID > 52";
  3. dv.Sort = "ID DESC";
  4. int c = dv.Count;
  5. if (c > 51)
  6. {
  7. for (int n = 50; n < c; n++)
  8. {
  9. dv.Delete(n);
  10. }
  11. }
  12. this.DataGrid1.DataSource = dv;
 

6.绑定数据操作

GridView.DataSource = ds;
GridView.DataMember = "Authors";
GridView.DataBind();
GridView.DataSource = ds.Tables["Authors"];
GridView.DataBind();
DataView dv = new DataView(ds.Tables["Authors"]);
dv.RowFilter = "state = 'CA'";
GridView.DataSource = dv;
GridView.DataBind();

DataSet与DataTable对象的更多相关文章

  1. 将Xml字符串转换成(DataTable || DataSet || XML)对象

    今天用到一个功能:就是把从数据库读出来的内容转换成XML字符串流格式,并输出给一个功能函数.在写的过程,为方便以后的使用,我对这一功能进行分装.该类的具体格式如下:XmlConvert类命名空间:Ni ...

  2. Winform开发之ADO.NET对象Connection、Command、DataReader、DataAdapter、DataSet和DataTable简介

    ADO.NET技术主要包括Connection.Command.DataReader.DataAdapter.DataSet和DataTable等6个对象,下面对这6个对象进行简单的介绍:(1)Con ...

  3. dataAdapter与dataSet和dataTable的填充

    对于dataAdapter与dataSet和dataTable的填充,可以分为1对1,1对n,n对n,3种情况. 以SqlDataAdapter为例. //(1)1对1 SqlDataAdapter ...

  4. ADO.NET基础02(语句参数化,配置文件,DataSet与DataTable)

    ADO.NET连接池 ado.net默认启用了连接池 *如何清空连接池?Connection的静态方法ClearAllPools(). ClearPool() Ado.net连接池使用总结: 1.第一 ...

  5. DataSet和DataTable详解

    先构建一个结构与用户请求数据结构相同的DataTable,然后将用户的请求数据填充到构建好的DataTable中,最后将DataTable添加到DataSet中. DataTable,,DataCol ...

  6. 关于PagedDataSource分页属性与DataSet和DataTable详解

    Asp.net提供了三个功能强大的列表控件:DataGrid.DataList和Repeater控件,但其中只有DataGrid控件提供分页功能.相对DataGrid,DataList和Repeate ...

  7. c# 数据库编程(利用DataSet 和 DataAdaper对象操作数据库--跨表操作)

    上篇文章我们介绍了如何利用DataSet 和 DataAdaper对象来对单张表进行操作. 本文我们将介绍如何进行跨表操作. 我们通过具体例子方式进行演示,例子涉及到三张表. 1)student表(学 ...

  8. c# 数据库编程(利用DataSet 和 DataAdaper对象操作数据库--单表操作)

    一.概述 前面2篇文章,介绍了使用SqlCommand对象利用sql命令来操作数据库. 这篇文章我们来介绍使用c#的DataSet 和 DataAdaper对象操作操作数据库. 先来介绍下这两个对象是 ...

  9. DataSet、DataTable、DataRow 复制

    DataSet.DataTable.DataRow 复制 DataSet 对象是支持 ADO.NET的断开式.分布式数据方案的核心对象 ,用途非常广泛.我们很多时候需要使用其中的数据,比如取得一个Da ...

随机推荐

  1. 利用cmdline和gradle快速编译出apk

    http://blog.csdn.net/qq_16628781/article/details/49365139 gradlew.bat clean build --info > bugtag ...

  2. CSS3学习笔记--line-height:150%与line-height:1.5的真正区别

    代码: <div style="line-height:150%;font-size:16px;"> 父元素内容 <div style="font-si ...

  3. Android NDK 同时编译多个Module

    LOCAL_PATH := $(call my-dir) ## ## NDK 支持同时编译多个Module: ## 在配置的时候,每个Module需要 以 include $(CLEAR_VARS)开 ...

  4. windows下Android利用ant自动编译、修改配置文件、批量多渠道,打包生成apk文件

    原创文章,转载请注明:http://www.cnblogs.com/ycxyyzw/p/4535459.html android 程序打包成apk,如果在是命令行方式,一般都要经过如下步骤: 1.用a ...

  5. Sql中的Merge和output

    先看merge, 不用merge时: --更新 update TA Value ) --插入没有的数据 insert into TA ,,Value from TB ) and TypeName=@v ...

  6. 使用before、after伪类制作三角形

    使用before.after伪类实现三角形的制作,不需要再为三角形增加不必要的DOM元素,影响阅读. <!DOCTYPE html><html><head>    ...

  7. Text3d

    有小bug,先弄这么多吧,晚了,碎觉了 ---------------------------------

  8. c++ 职责链模式(Chain of Responsibility)

    职 责链模式:使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系.将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处 理它为止.其思想很简单,考虑员工要求加薪.公司的管 ...

  9. mysql 显示行号,以及分组排序

    建表: CREATE TABLE `my_tb` ( `id` ) NOT NULL AUTO_INCREMENT, `parent_code` ) DEFAULT NULL, `code` ) DE ...

  10. HP P1008打印机如何打印特殊纸张

    一.问题的提出 HP P1008中间有一个进纸槽,这是干什么的? 二.问题的分析 查说明,说这个进纸槽是叫做优先进纸槽,用于各种非常规的纸张的打印. 三.问题的解决 弄一张特殊尺寸的纸张,打开要编辑的 ...