工具软件   办公软件   操作系统   网络安全   设计在线   程序开发   教程宝典   软件下载   软件论坛
您的位置:软件 > 开发者网络 > 微软开发专栏 > 技术专题 > 正文
ADO.NET实现应用程序数据访问层
[文章信息]
作者:Dan Fox
时间:2005-03-16
出处:MSDN
责任编辑:方舟
[文章导读]
实现数据访问功能是大多数使用.NET Framework的开发人员的核心工作
advertisement
热点推荐
· Easy Go Back帮你用好鼠标手势
· 3月15日软件精选 欣赏优美的代码
· Word窗口主要元素的显示和隐藏
· 提高Windows内存效率的几种方法
· 完美的C++:C++/CLI
[正文]

上一页  1 2 3 4  下一页

  规则4:仔细选择外部接口

  当您设计数据访问类的方法时,需要考虑它们将如何接收和返回数据。对于大多数开发人员而言,有三种主要选择:直接使用ADO.NET对象、使用XML和使用自定义类。如果您要直接公开ADO.NET对象,则可以利用两个编程模型中的一个。第一个模型包含DataSet和DataTable对象,它们对于断开连接的数据访问很有用。关于DataSet及其关联的DataTable,已在许多文章中进行过介绍,但是在需要处理已经与基础数据存储区断开连接的数据时,它们非常有用。换句话说,DataSet可以在应用层之间传递,即使这些层分布在不同的物理位置也可以进行传递,如在业务层和数据服务层被放在与表示服务不同的服务器群集上的情况下。

  另外,对于通过基于XML的Web Service返回数据的情况来说,DataSet对象也是理想的选择,这是因为它们可以序列化,因而可以在SOAP响应消息中返回。这有别于使用实现IDataReader接口的类(例如,SqlDataReader和OleDbDataReader)访问数据。这些数据读取器用于以只进、只读方式访问数据。这两者之间的巨大差异在于:DataSet和DataTable对象可以按值在应用程序域之间(因而也可以在相同或不同计算机上的进程之间)传递,而数据读取器则可以到处传递,并且总是按引用传递。请参见图5,其中Read和GetValues是在服务器进程中执行的,并且它们的返回值被复制到客户端。


图5 远程处理数据读取器

  该图着重显示了数据读取器如何存在于创建它的应用程序域中,以及对它的所有访问如何在客户端和服务器应用程序域之间产生往返行程。这意味着,只有当数据读取器在调用方所在的同一应用程序域中执行时,数据访问方法才应当返回这些数据读取器。在使用数据读取器时,还有其他两个需要考虑的问题。

  首先,在从数据访问类中的方法返回数据读取器时,需要考虑与该数据读取器相关联的连接对象的生存期。默认情况下,在调用方循环访问数据读取器时,连接会保持繁忙。遗憾的是,当调用方完成工作时,连接将保持开启状态,因此不会返回到连接池(如果启用连接池的话)。但是,您可以通过将CommandBehavior.CloseConnection枚举值传递给命令对象的ExecuteReader方法,来指示数据读取器在它的Close方法被调用时关闭连接。

  其次,为了将表示层从特定的Framework data provider(例如SqlClient或OleDb)分离,调用代码应当使用IDataReader接口而不是具体类型(例如SqlDataReader)来引用返回值。这样,如果应用程序从Oracle移植到SQL Server后端,并且数据访问类中的方法的返回类型进行了更改,则表示层无须更改。如果您希望数据访问类返回XML,则可以从System.Xml命名空间中的XmlDocument和XmlReader类(它们类似于DataSet和IDataReader)中进行选择。换句话说,当数据要从它的源断开连接时,您的方法应当返回XmlDocument(或XmlDataDocument),而XmlReader可以用来对XML数据进行流式访问。

  最后,您还可以决定用公共属性返回自定义类。这些类可以用Serialization属性标记,以便能够跨应用程序域进行复制。另外,如果您要从方法中返回多个对象,则可能需要强类型集合类。

Imports System.Xml.Serialization

<Serializable()> _
Public Class Book : Implements IComparable

<XmlAttributeAttribute()> Public ProductID As Integer
Public ISBN As String
Public Title As String
Public Author As String
Public UnitCost As Decimal
Public Description As String
Public PubDate As Date

Public Function CompareTo(ByVal o As Object) As Integer _
Implements IComparable.CompareTo

 Dim b As Book = CType(o, Book)
 Return Me.Title.CompareTo(b.Title)
End Function

End Class

Public NotInheritable Class BookCollection : Inherits ArrayList

Default Public Shadows Property Item(ByVal productId As Integer)
As Book

Get
 Return Me(IndexOf(productId))
End Get
Set(ByVal Value As Book)
 Me(IndexOf(productId)) = Value
End Set
End Property

Public Overloads Function Contains(ByVal productId As Integer) As Boolean
 Return (-1 <> IndexOf(productId))
End Function

Public Overloads Function IndexOf(ByVal productId As Integer) As Integer
 Dim index As Integer = 0
 Dim item As Book

 For Each item In Me
  If item.ProductID = productId Then
   Return index
  End If
  index = index + 1
 Next
 Return -1
End Function

Public Overloads Sub RemoveAt(ByVal productId As Integer)
 RemoveAt(IndexOf(productId))
End Sub

Public Shadows Function Add(ByVal value As Book) As Integer
 Return MyBase.Add(value)
End Function

End Class
               图6 使用一个自定义类

  图6包含了一个简单的Book类及其关联的集合类的示例。您会发现,Book类用Serializable进行了标记,以便跨应用程序域启用“按值(by value)”语义。该类实现了IComparable接口,以便当它包含在集合类中的时候,它将在默认情况下按Title排序。BookCollection类派生自System.Collections命名空间中的ArrayList,并且遮蔽了Item属性和Add方法,以便将集合限制为仅包含Book对象。通过使用自定义类,您可以获得对数据表示方法的完全控制,通过强类型化和IntelliSense提高开发人员的工作效率,并且消除对ADO.NET的调用方依赖性。但是,由于.NET Framework不包含任何与对象相关的映射技术(除了本质上是派生的DataSet类的类型化DataSet对象以外),因此该方法需要更多的代码。在这些情况下,您通常要在数据访问类中创建一个数据读取器,并且使用它来填充自定义类。


上一页  1 2 3 4  下一页

发表评论推荐给朋友我想参加相关培训打印我对此感兴趣订阅电子杂志
相关内容焦点新闻
  • ADO.NET2.0的十大新特性
  • 使用ADO.NET的最佳实践
  • ADO.NET实用技巧两则
  • DataSet的数据并发异常处理
  • 使用ADO.NET设计数据库应用程序
  • 3家搜索引擎集体诉讼8848 吕春维未敢出席
  • 杨元庆:没有准备不会获批的备用方案
  • 【315】华硕笔记本电脑漏电 存在设计缺陷
  • 军队信息化诞生新领域 电子军务呼之欲出
  • 世界经济论坛公布信息化程度全球最新排名
  • 2004政务绩效评估:政府门户尚处于发展阶段
  • 甲骨文出资5.15亿美元 意图收购RetekInc
  • 技术并购:帮你突破传统增长的“天花板”
  • Advertisement