VS2005和ASP.NET2.0中使用强类型数据

简介:
一、 简介

  作为开发人员,当我们在学习新技术时,例子可能是我们最大的敌人。而教程往往设计得易于理解,但是同时,它们常常加固了懒惰,低效性,甚至于危险的编 码习惯。再也没有比ADO.NET示例更能说明问题的了。在本文中,我们将准备分析一下强类型对象对于你的数据库开发的意义以及为什么在没有例子的情况下 你应该在应用程序中尽量使用强类型对象。

  具体地说,我们将分析怎样在Visual Studio 2005中创建和使用强类型DataSet。正如本文所探讨的,相对于其它可选的弱类型化的数据存取技术,强类型DataSet提供了很多优点;并且,借 助于Visual Studio 2005,创建和使用强类型DataSet比以往更为容易。

   二、 强类型对象基础及优点

  为了理解强类型化的含义,不妨让我们先考虑一下约会的例子。如果你是一个单身汉,那么,你盼望与什么类型的人约会呢?你可能已经有了自己具体的标准, 如富裕且吸引人或可能是居住条件优越而性感。无论你的条件如何,当你决定想与谁在一起呆更长的时间时,你都难免有一套自己的约会标准。如果你很明智,可以 列出一个经过事先深思熟虑的列表,这样可以帮助你节约不必要的感情付出。把一项"非酗酒"的条件加入到你的约会标准中将会节约你大量的时间,并且允许你把 你的时间和精力用于与更好的候选者约会。

  你可能疑惑,这怎么能与编程进行比较呢?请听我的解释。ADO.NET数据存取对象的设计是为了实现最大的灵活性。除非你遇到相当大的麻烦,否则,当 你从数据库读取数据时,你都会使用大量普通的未经类型化的对象-当然,.NET框架完全允许这样做。而使用我们的约会类比法,总是把你的关系数据当作泛型 对象则有点象承认"我只与满足我条件的人约会"。难道你不能稍微放宽一些条件吗?作为你的朋友,我必须建议你"先确定一些标准,再精简一下你的列表!"也 许更好些。

  正如忽视筛选你要约会的人能够导致未来的关系问题,与你的对象保持"松耦合"能够给你的代码带来错误。另外,因为如果你让任何旧对象"出入"你的子程 序的话,那么,直到你的应用程序在运行时刻执行时,你可能才会知道存在问题。在我们的日期约会类比中,在运行时刻捕获错误很类似于你与你的约会者在一家时 髦的意大利餐馆进行一场痛苦而尴尬的讨论。是的,你发现了这个问题;但是,如果你已经事先计划好的话,那么你的结果就不会是"一群用餐者盯着你,而你满身 是意大利烤碎肉卷"。如果你简单地把一些更紧密的标准应用于你的代码中,那么在你的应用程序开始运行前(在编译时刻)你就能够捕获错误。例如,请考虑下面 的示例代码:

string FirstName = myrow.("FirstName").ToString();

  上面的DataRow就是非类型化的;结果,你必须以一个串形式作为你要查询的列名来存取这个值(或者,使用这个列集合中的列的索引值)。很可能,这 个列真正存在。一个DataRow列的数据类型是对象;我们假定FirstName列的基本数据类型是字符串,但是,我们必须显式地把它转化成一个字符串 以便使用它。如果列名发生变化(例如,你把它改为PersonFirstName),那么编译器是不能通知你的。千万不要这样!因此,如果你的代码看起来 更象如下形式,那么你的生活就会更容易些而你的代码将更为可靠:

string FirstName = PersonRow.FirstName;

在第二个例子中,我们拥有一个强类型行,并且我们知道FirstName属性是字符串类型。在此,不会出现杂乱的列名,而且也不存在杂乱的对象转换问题。编译器为我们作类型检查,并且我们可以继续进行其它任务而不必担心是否我们已经正确输入了列名。

对于所有其它列也是如此;总之,当你能够使用一个更为具体的类型时,你永远不应该使用一个泛型对象。但是,请等一下。该强类型对象出自何处?我想我能 够告诉你这些对象是为你自动创建的。然而,正如要建立良好的关系需要时间和精力一样,强类型化你的对象也需要付出其它努力。好的方面在于,这里所花费的额 外时间是值得的,而且节省了将来更多的花在调试上的时间。

存在若干种可以实现强类型化的方法,在本文余下的部分中,我们将讨论怎样在Visual Studio 2005中创建强类型DataSet;当然,还将分析一下这样做的优点和缺点。
  三、 在VS 2005中创建强类型DataSet

其实,强类型DataSet是一些提前定义了它们自己的列与表的泛型DataSet,这样编译器已经知道它们将会包含什么内容。不是把你的数据包装为 一个"露指手套",一个强类型DataSet恰似一个"手套"。每一个Visual Studio的后续版本会使得强类型化一个DataSet的过程更为容易。在这个示例中,我们将使用来自于SQL Server 2005中的AdventureWorks数据库。这只要简单地执行如下步骤:

1. 打开Visual Studio,然后创建一个新的ASP.NET网站。

2. 在Solution Explorer中,占击以添加一个新项并且选择DataSet,并命名为AdventureWorks.xsd。Visual Studio推荐把这个DataSet文件放到App_Code文件夹下。

3. 这个AdventureWorks.xsd将在设计模式下打开,并且激活"TableAdapter Configuration"向导。现在,仅仅点击一下"Cancel"即可。

4. 定位到Server Explorer工具箱,导航到你的SQL Server 2005数据库和AdventureWorks数据库。(如果你还没有安装AdventureWorks数据库的话,你可以从微软的SQL Server 2005 Samples and Sample Databases下载页面下载它,还有另外的SQL Server 2005示例。)

5. 把SalesOrderHeader和SalesOrderDetail表拖动到你的DataSet设计器窗口。现在,这个窗口应该类似于下面的屏幕快 照。注意,对于我们加入的每个表,Visual Studio都创建一个强类型DataTable(该名称是基于原始的表)和一个TableAdapter。这个DataTable为我们定义了每一个 列。这个表适配器是我们用来填充这个表的对象。缺省情况下,我们有一个Fill()方法,由它找到表中的每一行。



这个强类型DataSet将返回在这两个表中的所有记录。既然AdventureWorks数据库包含大量的订单信息,那么我们为什么不创建一个更为 具体些的查询呢?我们可以把方法添加到我们的TableAdapter对象来检索一个更为具体的表的记录子集。首先,右击 SalesOrderHeaderTableAdapter,并且选择"Add|Query"。选择"Use SQL statements"并且点击Next按钮。然后,选择"SELECT which returns rows"并且点击Next按钮。最后,在窗口中输入下列查询(或使用Query Builder来实现相同的任务):

SELECT
SalesOrderID, RevisionNumber, OrderDate, DueDate, ShipDate, 
Status, OnlineOrderFlag, SalesOrderNumber, PurchaseOrderNumber, 
AccountNumber, CustomerID, ContactID, SalesPersonID, TerritoryID, 
BillToAddressID, ShipToAddressID, ShipMethodID, CreditCardID, 
CreditCardApprovalCode, CurrencyRateID, SubTotal, TaxAmt, Freight, 
TotalDue, Comment, rowguid, ModifiedDate 
FROM Sales.SalesOrderHeader
WHERE (OrderDate > @OrderDate)

  这个SQL查询是一个简单的SELECT查询,它有一个@OrderDate参数以进一步缩小结果范围。这样可以防止我们返回数据库的每一个订单。点 选"Fill a DataTable"和"Return a DataTable"复选框,然后点击Finish。在添加这个SELECT语句后,你的设计者现在应该有一个外部查询已经添加到这个 SalesOrderHeaderTableAdapter,请参考下面的屏幕快照。


  四、 在一个ASP.NET页面上使用强类型DataSet

  通过创建强类型DataSet,我们可以仅通过编写几行代码就可以实现容易地在一个ASP.NET页面显示这些数据。首先,在你的网站上创建一个 ASP.NET页面并且在设计模式中观察它。然后,拖放一个GridView控件到其上,保持其ID为GridView1。打开ASP.NET页面的源代 码并且在文件的顶部导入AdventureWorksTableAdapters命名空间(在C#中,该语法为:"using AdventureWorksTableAdapters;")。最后,把下列代码添加到Page_Load事件处理器中:

//创建SalesOrderHeaderTableAdapter
SalesOrderHeaderTableAdapter salesAdapter = 
new SalesOrderHeaderTableAdapter();
//得到发生于2004年7月1日之后的订单
AdventureWorks.SalesOrderHeaderDataTable Orders = 
salesAdapter.GetDataBy(new DateTime(2004, 7, 1));
//把订单结果绑定到GridView
this.GridView1.DataSource = Orders;
this.GridView1.DataBind();

  这段代码是很简单的。我们创建SalesOrderHeaderTableAdapter的一个实例-我们将使用它来填充DataTable。注意, 不是声明一个泛型DataTable,我们声明了一个SalesOrderHeaderDataTable类型的对象。为了填充这个DataTable, 我们调用GetDateBy()方法并且传递给它一个DateTime对象。还要注意,甚至这个检索命令也是强类型化的,因为我们必须传递一个 DateTime对象,而不仅仅是一个泛型对象。下面的屏幕快照显示了上面示例代码的清晰结果。



  除了通过代码把结果绑定到GridView外,你还可以使用一个ObjectDataSource,设置它的TypeName属性为 AdventureWorksTableAdapters.SalesOrderHeaderTableAdapter,并且把它的 SelectMethod设置为GetData或GetDataBy。

   五、 使用强类型DataSet插入、更新和删除数据

  在本文中,我们已经看到了怎样使用一个强类型DataSet从一个数据库中选择数据。然而,你还可以使用这些工具来插入、更新和删除基本的数据库数据。

  除了不必编写代码来存取数据库外,使用这个强类型化的DataSet的另外一个很大的优点是,在此不存在编译器不能检查的字符串列名潜伏在我们的代码 并且我们不必进行任何对象转换。如果我们曾经改变过我们的数据库模式,那么一旦我们更新我们的AdventureWorks.xsd文件,我们将注意到在 编译期间的存在于我们的应用程序中的所有的巨大变化。

   六、 小结

  其实,除了使用强类型DataSet外,还有另外的方法来实现你的应用程序的强类型化。你可以创建定制类-比DataSet更为轻量级并且能够正确地 响应于你的数据库。而且,还有一些第三方软件开发者提供工具来自动化这一过程。其中,一个特别的产品是LLBLGen Pro,就是我比较喜欢的工具之一,我还写了有关于它的一本书:《Rapid C# Windows Development: Visual Studio 2005, SQL Server 2005,and LLBLGen Pro》。另外一个流行的工具是CodeSmith。甚至微软也在使用一个与之类似的工具-DLINQ,它仍处于测试阶段,至少在下一年中不会上市。

  如果你使用Visual Studio强类型DataSet方法,那么你不需要购买任何另外的软件-这是一个明显的优点。所有这些解决方案都有其各自不同的特征和优点,但是强类型 化你的关系数据的主要优点还在于:可靠性,更少的错误和更少的调试时间花费;另外,分析数据库模式变化的影响并实现它们也更为容易。最后,非常希望你已经 了解到强类型化的优点。祝你幸运!





















本文转自朱先忠老师51CTO博客,原文链接:http://blog.51cto.com/zhuxianzhong/59745 ,如需转载请自行联系原作者


相关文章
|
10月前
|
网络协议 定位技术 网络安全
IPIP.NET-IP地理位置数据
IPIP.NET 是一家专注于 IP 地理位置数据的提供商,基于 BGP/ASN 数据与全球 800+ 网络监测点技术,提供高精度的 IPv4 和 IPv6 定位服务。其核心服务包括地理位置查询、详细地理信息和网络工具等,广泛应用于网络安全、广告营销、CDN 优化等领域。数据覆盖全球,支持多语言,每日更新确保实时性。IPIP.NET 提供 API 接口、离线数据库及多种语言 SDK,方便开发者集成使用。
1875 0
|
SQL XML 关系型数据库
入门指南:利用NHibernate简化.NET应用程序的数据访问
【10月更文挑战第13天】NHibernate是一个面向.NET的开源对象关系映射(ORM)工具,它提供了从数据库表到应用程序中的对象之间的映射。通过使用NHibernate,开发者可以专注于业务逻辑和领域模型的设计,而无需直接编写复杂的SQL语句来处理数据持久化问题。NHibernate支持多种数据库,并且具有高度的灵活性和可扩展性。
358 2
|
存储 C#
揭秘C#.Net编程秘宝:结构体类型Struct,让你的数据结构秒变高效战斗机,编程界的新星就是你!
【8月更文挑战第4天】在C#编程中,结构体(`struct`)是一种整合多种数据类型的复合数据类型。与类不同,结构体是值类型,意味着数据被直接复制而非引用。这使其适合表示小型、固定的数据结构如点坐标。结构体默认私有成员且不可变,除非明确指定。通过`struct`关键字定义,可以包含字段、构造函数及方法。例如,定义一个表示二维点的结构体,并实现计算距离原点的方法。使用时如同普通类型,可通过实例化并调用其成员。设计时推荐保持结构体不可变以避免副作用,并注意装箱拆箱可能导致的性能影响。掌握结构体有助于构建高效的应用程序。
616 7
|
开发框架 .NET 数据库连接
闲话 Asp.Net Core 数据校验(三)EF Core 集成 FluentValidation 校验数据例子
闲话 Asp.Net Core 数据校验(三)EF Core 集成 FluentValidation 校验数据例子
258 1
|
开发框架 JSON 前端开发
利用查询条件对象,在Asp.net Web API中实现对业务数据的分页查询处理
利用查询条件对象,在Asp.net Web API中实现对业务数据的分页查询处理
|
开发框架 前端开发 算法
分享 .NET EF6 查询并返回树形结构数据的 2 个思路和具体实现方法
分享 .NET EF6 查询并返回树形结构数据的 2 个思路和具体实现方法
248 0
|
编译器 C#
C#.Net筑基-类型系统②常见类型 --record是什么类型?
`record`在C#中是一种创建简单、只读数据结构的方式,常用于轻量级数据传输。它本质上是类(默认)或结构体的快捷形式,包含自动生成的属性、`Equals`、`ToString`、解构赋值等方法。记录类型可以继承其他record或接口,但不继承普通类。支持使用`with`语句创建副本。例如,`public record User(string Name, int Age)`会被编译为包含属性、相等比较和`ToString()`等方法的类。记录类型提供了解构赋值和自定义实现,如密封的`sealed`记录,防止子类重写。
313 6
|
开发框架 .NET API
.NET Core 和 .NET 标准类库项目类型有什么区别?
在 Visual Studio 中,可创建三种类库:.NET Framework、.NET Standard 和 .NET Core。.NET Standard 是规范,确保跨.NET实现的API一致性,适用于代码共享。.NET Framework 用于特定技术,如旧版支持。.NET Core 库允许访问更多API但限制兼容性。选择取决于兼容性和所需API:需要广泛兼容性时用.NET Standard,需要更多API时用.NET Core。.NET Standard 替代了 PCL,促进多平台共享代码。
288 0
|
存储 编译器
【.NET Core】可为null类型详解
【.NET Core】可为null类型详解
406 0