自定义实体类简介(1)

摘要:有些情况下,非类型化的 DataSet 可能并非数据操作的最佳解决方案。本指南的目的就是探讨DataSet 的一种替代解决方案,即:自定义实体与集合。(本文包含一些指向英文站点的链接。)


引言
ADODB.RecordSet 和常常被遗忘的 MoveNext 的时代已经过去,取而代之的是 Microsoft ADO.NET 强大而又灵活的功能。我们的新武器就是 System.Data 名称空间,它的特点是具有速度极快的 DataReader 和功能丰富的 DataSet,而且打包在一个面向对象的强大模型中。能够使用这样的工具一点都不奇怪。任何 3 层体系结构都依靠可靠的数据访问层 (DAL) 将数据层与业务层完美地连接起来。高质量的 DAL 有助于改善代码的重新使用,它是获得高性能的关键,而且是完全透明的。

随着工具的改进,我们的开发模式也发生了变化。告别 MoveNext 并不只是让我们摆脱了繁琐的语法,它还让我们认识了断开连接的数据,这种数据对我们开发应用程序的方式产生了深刻的影响。

因为我们已经熟悉了 DataReader(其行为与 RecordSet 非常类似),所以没花多长时间就进一步开发出 DataAdapter、DataSet、DataTable 和 DataView。正是在开发这些新对象的过程中不断得到磨炼的技能改变了我们的开发方式。断开连接的数据使我们可以利用新的缓存技术,从而大大提高了应用程序的性能。这些类的功能使我们能够编写出更智能、更强大的函数,同时还能减少(有时候甚至是大大减少)常见活动所需的代码数量。

有些情况下非常适合使用 DataSet,例如在设计原型、开发小型系统和支持实用程序时。但是,在企业系统中使用 DataSet 可能并不是最佳的解决方案,因为对企业系统来说,易于维护要比投入市场的时间更重要。本指南的目的就是探讨一种适合处理此类工作的 DataSet 的替代解决方案,即:自定义实体与集合。尽管还存在其他替代解决方案,但它们都无法提供相同的功能或无法获得更多的支持。我们的首要任务是了解 DataSet 的缺点,以便理解我们要解决的问题。

记住,每种解决方案都有优缺点,所以 DataSet 的缺点可能比自定义实体的缺点(我们也将进行讨论)更容易让您接受。您和您的团队必须自己决定哪个解决方案更适合您的项目。记住要考虑解决方案的总成本,包括要求改变的实质所在以及生产后所需的时间比实际开发代码的时间更长的可能性。最后请注意,我所说的 DataSet 并不是类型化的 DataSet,但它确实可以弥补非类型化的 DataSet 的一些缺点。


DataSet 存在的问题
缺少抽象


寻找替代解决方案的第一个也是最明显的原因就是 DataSet 无法从数据库结构中提取代码。DataAdapter 可以很好地使您的代码独立于基础数据库供应商(Microsoft、Oracle、IBM 等),但不能抽象出数据库的核心组件:表、列和关系。这些核心数据库组件也是 DataSet 的核心组件。DataSet 和数据库不仅共享通用组件,不幸的是,它们还共享架构。假定有下面这样一个 Select 语句:

SELECT UserId, FirstName, LastName
FROM Users



我们知道这些值可以从 DataSet 中的 UserId、FirstName 和 LastName 这些 DataColumn 中获得。

为什么会这么复杂?让我们看一个基本的日常示例。首先我们有一个简单的 DAL 函数:

'Visual Basic .NET
Public Function GetAllUsers() As DataSet
Dim connection As New SqlConnection(CONNECTION_STRING)
Dim command As SqlCommand = New SqlCommand("GetUsers", connection)
command.CommandType = CommandType.StoredProcedure
Dim da As SqlDataAdapter = New SqlDataAdapter(command)
Try
Dim ds As DataSet = New DataSet
da.Fill(ds)
Return ds
Finally
connection.Dispose()
command.Dispose()
da.Dispose()
End Try
End Function

//C#
public DataSet GetAllUsers() {
SqlConnection connection = new SqlConnection(CONNECTION_STRING);
SqlCommand command = new SqlCommand("GetUsers", connection);
command.CommandType = CommandType.StoredProcedure;
SqlDataAdapter da = new SqlDataAdapter(command);
try {
DataSet ds = new DataSet();
da.Fill(ds);
return ds;
}finally {
connection.Dispose();
command.Dispose();
da.Dispose();
}
}



然后我们有一个页面,它使用重复器显示所有用户:

<HTML>

<body>

<form id="Form1" method="post" runat="server">

<asp:Repeater ID="users" Runat="server">

<ItemTemplate>

<%# DataBinder.Eval(Container.DataItem, "FirstName") %>

<br />

</ItemTemplate>

</asp:Repeater>

</form>

</body>

</HTML>

<script runat="server">
public sub page_load
users.DataSource = GetAllUsers()
users.DataBind()
end sub
</script>



正如我们所看到的那样,我们的 ASPX 页面利用 DAL 函数 GetAllUsers 作为重复器的 DataSource。如果由于某种原因(为了性能而降级、为清楚起见而进行了标准化、要求发生了变化)导致数据库架构发生变化,变化就会一直影响 ASPX,即影响使用“FirstName”列名的 Databinder.Eval 行。这将立刻在您脑海中产生一个危险信号:数据库架构的变化会一直影响到 ASPX 代码吗?听起来不太像 N 层,对吗?
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值