让开发变得更快速、更简单——类型化DataSet的使用

     DataSet相信大家都很熟悉了,但是什么是类型化的DataSet?在ASP.NET三层的WEB应用程序中经常可以看到实体类,实体类的出现让人们可以在开发中有更加友好的访问数据的方法,一个实体类中其实就是封装了某个数据表的所有字段,把这个数据表作为一个对象来控制它的所有属性。类型化DataSet在开发中的作用就好象实体类,它的功能也和实体类相仿,我们可以把一张数据表作为一个封装好的实体类来使用。说到这里大家可能想起来一个词“强类型”,对!我今天介绍的类型化DataSet其实就是有的人所说的“强类型DataSet”,这里我不用这个“强类型”来修饰这样的DataSet,因为“强”类型的Dataset其实也有它的弱点,这些弱点我会在下面的介绍中一一道出,所以它不是真正的“强”,这里就叫它“类型化”的准确一些吧。

     类型化DataSet是从DataSet派生的,当然,同时派生出来的类不只有类型化DataSet,也有派生于DataTable的类型化DataTable、派生于DataRow的类型化DataRow等等。而这些派生出来的类都定义了多个附加的属性和方法,为基础类提供了安全而方便友好的访问,并且可以提高设计效率和运行效率。

     类型化DataSet简化了编程,同时不容易出现错误,想象一下,普通DataSet中,只能通过列名索引访问一个列的值,如果把索引名字写错,这个时候编译器是不会发现错误的,但是对于类型化DataSet就不会了,如果索引写错编程人员马上就可以知道,因为类型化DataSet的列是被当作对象的属性来访问的。

     还有就是如果你在你的类型化DataSet中包含多数据集,同时在生成的XSD文件中对这些数据集建立关系和约束,那么,类型化的DataSet会自动生成一些方法来反应这些关系和约束,但是使用普通的DataSet的时候这些你都需要自己做。

     关于有人说VS内置的类型化DataSet性能方面不尽如人意,我觉得,类型化DataSet在创建实例对象的时候要比非类型化DataSet多一些开销(在时间和内存空间上),但是类型化DataSet在填充数据的时候要比非类型化DataSet快,这是因为.NET的DataAdapter在填充数据之前就已经知道应该怎么去Fill一个类型化的DataSet,相比之下,非类型化DataSet就要访问两次读取数据,第一次访问取得数据表的数据结构信息,第二次访问的时候才真正的Fill数据。

     说道这里,大家一定认为类型化DataSet这还不是“强”?被称作“强类型DataSet”一点也不为过吧?是的,现在看来类型化DataSet的确是够“强”,我第一次接触这样的DataSet的时候也接触的是“强类型”的,但是,类型化DataSet有一个它致命的弱点,就是不如非类型化的DataSet灵活,因为类型化DataSet一旦建立,那么它的数据表的结构也就固定了,没有办法更改,如果需要修改的话,就必须从新生成!试想一下,如果在开发中需要对其修改,比如添加或者去除字段的话,就会非常非常麻烦,而非类型化DataSet可以根据自己的需要随时修改,所以,在这里,说类型化DataSet“强”也是片面的。

     说了这么多,来看看具体在VS中这么使用类型化的DataSet吧!

     添加新项-从弹出窗口中选择数据-选择数据集,然后起一个名字,点确定。现在就可以看到设计视图了。

  

  

  

  下一步要做的就是打开服务器资源管理器,然后找到要创建到数据集里的数据表,把它拖到设计视图中,然后保存,一个类型化DataSet就建立完成了。

  

  (关于例子:在这片文章中我所使用的例子都以这样的数据表表来举例:)

1 create table T_Users(Id int primary key identity(1,1) not null,Name nvarchar(20) not null,Age int not null,Tel nvarchar(20) not null)

 

 

  

类型化DataSet的使用以及特点:

 

  首先,类型化DataSet简化了设计(编程)过程,这也是我喜欢类型化DataSet的主要原因,在普通DataSet的应用中,如果想要访问一个数据表中的某行的某一个字段的值,我们需要这样做:

  比如读出T_Users的第一个用户Name信息:

 1 string connStr="Data Source=.\\sqlexpress;Initial Catalog=test;Integrated Security=True";
 2 SqlConnection conn = new SqlConnection(connStr);
 3 conn.Open();
 4 SqlCommand cmd = conn.CreateCommand();
 5 cmd.CommandText = "select Name from T_Users";
 6 DataSet ds = new DataSet();
 7 SqlDataAdapter adapter = new SqlDataAdapter(cmd);
 8 adapter.Fill(ds);
 9 DataTable dt = ds.Tables[0];
10 string name = dt.Rows[0]["Name"].ToString();
11 return name;

  如果是类型化DataSet我们只需要这么做,(注意这里先要using bbb.DataSetT_UsersTableAdapters;):

T_UsersTableAdapter adapter = new T_UsersTableAdapter();
bbb.DataSetT_Users.T_UsersDataTable users = adapter.GetData();
bbb.DataSetT_Users.T_UsersRow user = users[0];
string Name = user.Name;
return Name;

 

  看到了吧?这里的表的关键字索引都有友好的自动提示。

  

  这里的T_UsersTableAdapter也就是非类型化DataSet的SqlDataAdapter,T_UsersDataTable也就是非类型化DataSet的DataTable,T_UsersRow也就是非类型化DataSet的DataRow,是不是很好用?只要一“点”就能把表里的关键字索引像一个类的属性一样“点”出来,这样大幅度的简化了开发过程,而且以后的编码人员在二次开发的时候,也不需要牢记每一个关键字索引到底是什么,因为这里有我们要的所有了。而且省略了之前的SqlConnection,SqlCommand等等的操作,因为VS已经自动为什么生成了,这里可能有人会问,那个adapter.GetData();是什么?这个是VS为我们生成的一个访问数据表方法,这个GetData()方法也是默认建立类型化DataSet的时候自动生成的,它的CommandText 也就是"select * from T_Users";到这里大家可能会说了,一个"select * from T_Users"怎么能够用呢?是啊,在下面的说明中,我会说道怎么自己给类型化的DataSet添加其他方法,我们就根据对数据的“增,删,改,查”简单操作做出相应的方法吧,以后在使用中就要自己根据不同的需要建立了。

 

  

  例子二:利用类型化DataSet增加一个用户,用户Name为Pangzi,Age为22,电话号码为123:

    第一步,双击打开刚刚建立的DataSetT_Users,为它添加一个关于Insert的查询。名字就叫做“InsertNewUser”吧,如图:

 

  这样我们的“InsertNewUser”就建立好了,使用如下:

1 T_UsersTableAdapter adapter = new T_UsersTableAdapter();
2 adapter.InsertNewUser("Pangzi", 22, "123");

 

  简单吧?是不是有点已经不想用原来的非类型化DataSet了呢?

  例子三:利用类型化DataSet删除刚刚加入的用户,建立方法为“DeleteUserByName”:

  建立方法前几个步骤一样,就是sql语句的时候相应的改动,如下图:

使用:

1 T_UsersTableAdapter adapter =new T_UsersTableAdapter();
2             adapter.DeleteUserByName("Pangzi");

  例子四:利用类型化DataSet修改用户名为Hexu的Tel为000000,名字为“UpdateTelByName”还是先建立查询,前几步骤还是一样,sql改一下,如图:

  

使用如下,还是可以得到友好的自动帮助,这里就不多少了:

1 T_UsersTableAdapter adapter =new T_UsersTableAdapter();
2 adapter.UpdateTelByName("000000", "Hexu");

  还有就是注意在使用的时候,如果在读出数据后,修改字段值,需要运行adapter.Update();方法,为什么呢?以为类型化DataSet也和非类型化DataSet一样,是将数据先放在了内存中,如果只做赋值操作的话,修改的内容只是保存在内存中,而没有updata到这真的数据库中。这里的adapter.Update();也就和非类型化DataSet的ExecuteNonQuery();是一样的。

  

例子:

T_UsersTableAdapter adapter =new T_UsersTableAdapter();
var users = adapter.GetData();
var user = users[0];
user.Name = "HHexu";
adapter.Update(users);

相比之下,类型化DataSet和非类型化DataSet的优、缺点:

1、非类型化DataSet只能通过列名引用,就像例子一一样,如果写错了列名编译时不会发现错误,因此开发时必须要记着列名。

2、int age=Convert.ToInt32(dataset.Rows[0]["Age"]),取到的字段的值是object类型,必须小心翼翼的进行类型转换,不仅麻烦,而且容易出错。

3、将非类型化DataSet传递给其他使用者,使用者很难识别出有哪些列可以供使用。

4、非类型化DataSet运行时才能知道所有列名,数据绑定麻烦,无法使用Winform、ASP.Net的快速开发功能。而类型化DataSet访问不但更易于读取,而且完全受   Visual   Studio“代码编辑器”中   IntelliSense   的支持。

5、就是非类型化DataSet致命缺点,无法更新表的结构。

 

  最后的总结,关于类型化DataSet的使用技术重点还有很多,这里笔者只是介绍了入门的方法,在以后的项目中还是多自己动脑利用类型化DataSet让开发变得更快速、更简单。

 

 

 

 

 

posted @ 2012-11-03 23:18  Happy Coder  阅读(3448)  评论(6编辑  收藏  举报