ADO.NET(DataView)

source:http://www.cnblogs.com/hssl/archive/2008/10/25/1319119.html

     上一篇我们讲了dataset的内部构成和如何往里面填充数据.当一个dataset被填充上数据后我们就可以用个数据绑定控件来绑定到dataset里的datatable了,然后就可以显示出里面的数据了.比如: GridView1.DataSource = ds.Tables[0].DefaultView,这样数据被显示出来了.很奇怪ds.Tables[0].DefaultView怎么多个DefaultView这玩意.有什么作用?我们把它去掉直接用ds.Tables[0]发现也可以.那这个东西有什么用?官方的解释是:获取可能包括筛选视图或游标位置的表的自定义视图.简单的说就是:获取表的视图.什么叫表的视图?表指的就是datatable,也就是datatable的视图.datatable就是datatable还要视图干什么?有什么作用?可以这么解释,datatable是存放是数据的,而且存放在内存中,可以被程序去处理.但是datatable并不能把这些数据呈现出来被我们肉眼看到.那我们要把这些数据显示出来被我们看到,那就要用视图了.视图嘛,字面意思就是,可视化图形的意思.现在知道,视图的作用就是把datatable里的数据显示出来能被我们看到的.为了能有个形象的理解,打个不准确的比喻吧.水,是无色透明的.那么我们怎么能看到水呢?我们用个杯子去装水,是不是就能看到水的形状了.是什么形状呢?当然取决于杯子的形状,用圆形杯子装水,我们看到的水的形状就是圆柱体的.用方形杯子装水,我们看到的水形状就是立方体的.现在我告诉你,datatable里的数据就相当于水,视图就相当于杯子.那么要让数据(水)显示出来给我们看到,是不是要用个视图(杯子)去装数据啊.现在是否对视图有个感性的认识了,它的主要作用就是显示数据的.说白了视图就是格式化输出数据的.可以联想到html语言就相当于视图,而里面的文字就相当于数据.例如在html中有:<b>数据</b>那么'数据'二字显示的就是粗体的.为什么显示粗体?因为html(视图)能让它(数据)显示,并能控制它(数据)显示的样式.(插一句,html的作用是用来显示数据的(图片,文字.等等都行)的,那么数据放哪呢?可以从数据库里读出数据来然后通过html显示,也可以把数据存放xml文件里,现在就很流行用xml来存放数据,用html来显示.也就是xml+html技术.xml现在是很火的一个东东,后面我们再详细探讨探讨xml的一些知识).上面讲了那么多废话无非是想说:视图是用来显示数据的.那么我有个视图没有数据,可有意义?没有.光有视图没有任何数据,视图去显示谁呢?就是无用的废物了.那么我们有数据没有视图可有意义呢?有,我们不想显示这些数据,就不一定非要搞个视图了吧.可见,我们有个视图必然要有数据才有意义.程序中就是这样,有视图肯定有数据.而数据我们可以想象成就装在视图中(水装在杯子中嘛),我们就一组数据,可以搞几个不同的视图啊,当把数据放到不同的视图里,显示出来的就是不一样的效果的.同样,把一个视图改变了那么这个视图里的数据显示出来的的样式就改变了,可见视图对数据来说还是瞒重要的一个东西.在程序中,视图不仅能显示数据,也能实现对数据的增删改查.因为可以看做数据装在视图里嘛,视图当然能对数据进行操作.回想下,我们说过dataset可以看做是个小型的数据库.既然是数据库,肯定能增删改查嘛,怎么做到呢?把数据放到视图里用视图来操作.

(上面说的真是够罗嗦了,发现我越来越唐僧了,只怪我脑子不灵活,理解能力差,所以把知识表达的容易理解才行)

好了讲了这么多,我们来看看在程序中到底怎么去用视图.

在程序中,表示视图的类是:DataView.也就是说在程序中DataView就是视图,那么数据呢,数据当然是datatable中的数据,而datatable只管把数据装起来,不会显示.所以我们可以创建一个视图把datatable放到视图里,也就是把数据放进去了.(datatable 可以想象成一个无形的表)

程序中创建一个视图就是 DataView dv = new DataView(),当然仅有视图没数据是没有意义的.所以我们创建视图的时候,都装载一个datatable进去,像这样创建的DataView dv = new DataView(datatable).这样就是把datatable配套一个视图对象(dataview)了.

 上面说了,视图可以控制变数据的显示样式的.我把视图的排列方式改变了,那么数据显示出来的样式也就改变了.DataView中有个方法叫DataView.Sort(),就是用来对数据排序的.可形象的想象为DataView里面是一层一层的像书架一样.书就是数据摆在书架的层上.调用这个方法后,相当于把书架里的每层按规律换一下.(上层换到下层...)

我们看看下面代码,代码中我们创建一个dataset,然后添加两个表分别是table1和table2,table1是学生表,有两个字段,id和name;table2是借书表,里有三个字段,id,tb1_id,bookname.然后用gridview1绑定到table1,用gridview2绑定到table2.
我们对table2进行排序,把table2里的字段添加到DropDownList中,我们通过选择DropDownList里的值,来设定按哪个字段来排序.

代码如下:

 

 1      static  DataView dv;
 2      static  DataSet ds;
 3      protected   void  Page_Load( object  sender, EventArgs e)
 4      {
 5        if (!Page.IsPostBack)
 6        {
 7            ds = new DataSet();
 8
 9            DataTable table1 = new DataTable("tb1");
10            DataTable table2 = new DataTable("tb2");
11
12            ds.Tables.Add(table1);
13            ds.Tables.Add(table2);
14
15            table1.Columns.Add("id"typeof(int));
16            table1.Columns.Add("name"typeof(string));
17
18            DataRow dr = table1.NewRow();
19            dr["id"= 1;
20            dr["name"= "张三";
21            table1.Rows.Add(dr);
22
23            //给table1添加一行的另一种写法
24            table1.Rows.Add(2"李四");
25
26            table2.Columns.Add("id"typeof(int));
27            table2.Columns.Add("tb1_id"typeof(int));
28            table2.Columns.Add("bookname"typeof(string));
29
30            table2.Rows.Add(11"高等数学");
31            table2.Rows.Add(21"大学英语");
32            table2.Rows.Add(32"平凡的世界");
33            table2.Rows.Add(42"追风筝的人");
34            table2.Rows.Add(52"堂吉可德");
35
36            //此方法必须调用,否则后面用筛选器时无效
37            table2.AcceptChanges();
38
39            //创建一个视图,作用table2里的数据
40            dv = new DataView(table2);
41
42            //把table2里的列添加到DropDownList1中
43            DropDownList1.Items.Clear();
44            DropDownList1.Items.Add("请选择");
45            foreach (DataColumn dc in table2.Columns)
46            {
47                DropDownList1.Items.Add(dc.ToString());
48            }

49
50            GridView1.DataSource = ds.Tables["tb1"].DefaultView;
51            GridView1.DataBind();
52            GridView2.DataSource = ds.Tables["tb2"].DefaultView;
53            GridView2.DataBind();
54        }

55
56    }

57
58      // 排序
59      protected   void  Button2_Click( object  sender, EventArgs e)
60      {
61        //设定要排序的列
62        dv.Sort = DropDownList1.SelectedItem.Text;
63
64        GridView2.DataSource = ds.Tables["tb2"].DefaultView;
65        GridView2.DataBind();
66    }

67

运行后,我们从DropDownList1里选个列,点排序按钮(button2),没反应,怎么搞都没反应就是不排序,怎么回事?我们看看64行代码:GridView2.DataSource = ds.Tables["tb2"].DefaultView. DefaultView是什么意思?它的意思是,当我们在dataset添加一个表个时候,会自动创建一个视图给这个表,也就是默认的视图.DefaultView的意思,就是默认的视图.ds.Tables["tb2"].DefaultView. DefaultView当然就是table2表的默认视图.看看我们排序的是哪个视图,是我们创建的dv啊.dv和DefaultView是两个不同的视图,dv进行排序了,DefaultView又没有排序GridView2绑定到默认视图上有什么用呢?同样,直接这么写GridView2.DataSource = ds.Tables["tb2"]也不行,因为这么写相当于只给GridView2提供了数据,而用的试图是GridView2里的(GridView这么强大的控件是能提出视图能力的).

那我们改下:

     // 排序
     protected   void  Button2_Click( object  sender, EventArgs e)
    
{
        
//设定要排序的列
        dv.Sort = DropDownList1.SelectedItem.Text;

        GridView2.DataSource 
= dv;
        GridView2.DataBind();
    }

这样就可以了,让GridView2绑定到dv视图上,因为用dv来排序的.我们不这样改也行,我们依然把GridView2绑定到table2的默认视图上(DefaultView)我们对这个DefaultView进行排序上一样的.看下面代码,效果是一样的

 1      // 排序
 2      protected   void  Button2_Click( object  sender, EventArgs e)
 3      {
 4        //设定要排序的列
 5        //dv.Sort = DropDownList1.SelectedItem.Text;
 6
 7        //GridView2.DataSource = dv;
 8        //GridView2.DataBind();
 9
10        //用table2的默认视图来排序
11        ds.Tables["tb2"].DefaultView.Sort = DropDownList1.SelectedItem.Text;
12
13        GridView2.DataSource = ds.Tables["tb2"].DefaultView;
14        GridView2.DataBind();
15    }

16

上面说了,视图单独存在没有意义,它要对数据操作才有意义.视图不仅能显示数据,还能按一定排列方式显示数据,还可以对数据进行增删改查,我们用代码来说明怎么进行这些操作,理解了视图后这些就很简单了.

 

 1      // 通过视图给table2增加一行
 2      protected   void  Button1_Click( object  sender, EventArgs e)
 3      {
 4        DataRowView drv = dv.AddNew();
 5        drv["id"= 100;
 6        drv["tb1_id"= 2;
 7        drv["bookname"= "张爱玲散文集";
 8
 9        GridView2.DataSource = dv;
10
11        //大家考虑下添加一行数据后,直接绑定到datatable数据中是否可以(也就是dataview添加一行,是否把数据添加到databale中了)
12        //GridView2.DataSource = ds.Tables["tb2"];
13        GridView2.DataBind();
14    }

15      // 通过视图删除table2一行
16      protected   void  Button3_Click( object  sender, EventArgs e)
17      {
18        //删除最后一行
19        dv.Delete(dv.Count - 1);
20
21        GridView2.DataSource = dv;
22        GridView2.DataBind();
23
24    }

25      // 通过视图更改table2一行
26      protected   void  Button4_Click( object  sender, EventArgs e)
27      {
28        //更新第0行bookname列
29        dv[0]["bookname"= "如来神掌";
30
31        GridView2.DataSource = ds.Tables["tb2"];
32        GridView2.DataBind();
33
34    }

35      // 在视图中查找
36      protected   void  Button5_Click( object  sender, EventArgs e)
37      {
38        //设置要查的列
39        dv.Sort = "bookname";
40        //在视图中找
41        string str = dv.Find("追风筝的人").ToString();
42
43        Response.Write(""+str+"");
44    }

45

上面代码我们讲了利用视图对数据进行增删改查,理解视图与数据的关系后上面的就很容易理解了.下面我们在看看视图对数据的筛选功能,什么叫筛选?顾名思义,就是从一堆东西里得到符合条件的,不符合条件的就不要.其实就是按条件查询的意思.....

dataview里有个属性RowFilter,这个属性就是接受条件的,看下面代码:

 1      protected   void  Button6_Click( object  sender, EventArgs e)
 2      {
 3        //设置筛选条件
 4        dv.RowFilter = TextBox1.Text;
 5
 6        GridView2.DataSource = dv;
 7        GridView2.DataBind();
 8
 9    }

10

 当我们在textbox1里输入像这样的条件:bookname='大学英语' ,那么视图就只让符合这个条件的那行显示,gridview2绑定上视图就行了.

此外视图还能对数据的版本进行筛选,什么叫数据的版本,比如我们在数据里删除一行,那么视图可以显示删除的那一行.还可以显示 未更改的行啊等等.刚才说了还能显示视图已删除的行,数据已经删除了怎么还能显示呢?其实视图删除一行数据只不过是在视图中把删除的那行做了个记号,并未真正删除数据中那行.同样我们修改一行数据后,视图也会在修改的这行中加个记号,增加一行视图也会加个记号的.获得相应的记号,就能得到相应记号的行了.我们来看段代码:

 1      protected   void  Button6_Click( object  sender, EventArgs e)
 2      {
 3        //设置筛选条件
 4        //dv.RowFilter = TextBox1.Text;
 5
 6        //通过删除记号(Deleted)来设置让筛选器显示被删除的行
 7        dv.RowStateFilter = DataViewRowState.Deleted;
 8
 9        GridView2.DataSource = dv;
10        GridView2.DataBind();
11
12    }

13

 当删除tabel2中的数据时候,上面的代码就可以把删除的显示出来了.当然还可以显示新增加数据等.要注意的是要想用这筛选器,在创建好table2表后必须要调用一个方法table2.AcceptChanges()否则,显示不出来筛选的数据,至于为什么?请大家找微软....

 关于dataview上面就泛泛的说了个大概...

下面我们说说dataset里的关系

上篇文章中说到,dataset由datatale和关系构成.关系就是datatable与datatable之间的关系.那么肯定一个dataset里不止一个表才存在表与表之间的关系.上面的列子恰好一个dataset里有两张表,一个是学生表(table1),另一个是学生借书表(table2),table2中有学生的id号(tb1_id),那么table1与table2就通过这个id有了关系.对于table2来说它里面的学生id(tb1_id),也是它的外键啊.table1与table2这样一种关系我们是心理明白的,但是程序并不知道,所以我们要在dataset里创建关系.

怎么创建?看下面代码:

 

 1      // 创建关系
 2      protected   void  Button7_Click( object  sender, EventArgs e)
 3      {
 4        //创建一个父/子这样的关系,关系的名字叫:tb12
 5        System.Data.DataRelation tb12 = new DataRelation("tb12", ds.Tables["tb1"].Columns["id"], ds.Tables["tb2"].Columns["tb1_id"]);
 6        //把创建的关系添加到dataset的关系集合中
 7        ds.Relations.Add(tb12);
 8
 9        //也可以通过这个写法来添加关系
10        //ds.Relations.Add("tb12", ds.Tables["tb1"].Columns["id"], ds.Tables["tb2"].Columns["tb1_id"]);
11    }

12

上面代码就是在dataset里添加了一个名为"tb12"的关系,一看便知道怎么创建了,创建好了怎么用?

第一个表table1里一个学生借了什么书,就可以通过刚才建立的关系来得到了.我们指定table1里一行(例如:table1.Rows[0]第0行),而datarow有个方法叫GetChildRows("关系名"),然后这个第0行就能通过关系,找到,它在table2里所有子行了.

看如下代码:

 

 1      // 得到子集
 2      protected   void  Button8_Click( object  sender, EventArgs e)
 3      {
 4        //创建一个表,2列的
 5        DataTable dt = new DataTable();
 6        dt.Columns.Add("name"typeof(string));
 7        dt.Columns.Add("bookname"typeof(string));
 8
 9        //指定table1里行号,指定好行号后就用这行调用dr.GetChildRows("关系名")方法,即可得到此行在table2里的子集
10        int row=int.Parse(TextBox1.Text);
11        DataRow dr= ds.Tables["tb1"].Rows[row];
12
13        //用上面table1里的一行,调用方法,得到此行在table2里子行的集合(可能table2里有很多行都是它的,所以返回的是数组)
14        DataRow[] drs = dr.GetChildRows("tb12");
15        foreach (DataRow ddr in drs)
16        {
17            //取出table1某行在table2里的子集,并添加到一个新表里(dt)
18            dt.Rows.Add(dr["name"], ddr["bookname"]);
19        }

20        
21        GridView3.DataSource = dt;
22        GridView3.DataBind();
23    }

24

上面就是简单的利用dataset的里表与表之间的关系的例子.通过关系,可以得到父表中某行在子里的子行.(用id来建立关系的)

 好了,关于dataview和关系就讲怎么多,这次说不是很好,估计会看的晕晕的.

说到现在dataset,发现都是我们自己往dataset里加数据,等于自己和自己玩,我们更多的时候希望能从数据库里读取数据放到dataset里,然后处理数据后再一下更新到数据库里.那么怎么把数据里的数据读取到dataset里呢?前面讲的SqlDataReader类可以从数据里得到数据,然后再一行一行的得到记录,再把字段对应的值得到,添加到dataset里的datatable里.这样是不是麻烦了点,而且效率也稍微慢了点,因为一次只能操作一行数据,还要保持程序与数据的连接.那么能不能一下就把数据库的数据装到dataset里呢?SqlDataAdapter类就能做到,下次就探讨一下SqlDataAdapter的用法和数据访问的并发控制.

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值