剖析 .Net 下的数据访问层技术(二)

** 其它 ** ** **

结束 ADO.NET 剖析前,不得不提提 DataReader 与 DataSet 间的兄弟

之争。

就作者所看过的资料,几乎所有的都建议实际情况具体分析,剩下

很少很少的则全凭个人习惯决定。

在学习 ADO.NET 时,作者也是抱着这样的想法,并反复牢记资料

上总结的那些条款(就像当年学习 GOF 23 条时那样,几乎可以倒背如

流了 J ),想到终有一日也可在 ADO.NET 下大展神威了。

可惜现实不随人愿,连续做了几个项目,无论规模大小,竟然全部

采用了 DataSet 解决方案!

此时,再回头看看学习 ADO.NET 时打开最为频繁的 PetShop 项目,

两相一比较,这才看出些许端倪。

简单的说, PetShop 采用了如下这种“ 曲线救国 ”的方式来实现数据

交换:

DataReader ** 获取 ** 数据 => ** 创建 ** 数据实体类 => 根据字段类型 填充

据实体类 => 将数据实体 添加 到列表类中(仅针对返回超过一条数据的

场合)

_ (补充:采用数据实体类或者集合类可以比较方便的实现 Cache Manament _ _ , _

_ 而普通的 DataReader _ _ 由于其数据读取方式限制,无法满足这种需求) _

这个过程与 DataAdapter.Fill() 所所产生的效果 大同小异 ,只不过,

在 Fill() 中 DataAdpater 自动创建 DataReader 去获取数据,之后创建

DataTable (相当于数据实体类),并根据字段类型填充 DataTable ,当然

,如果可能返回多条记录, DataTable 完全可以处理,就没必要去实现列

表操作了。

可能读者马上产生了疑问:既然如此, PetShop 中为何还需要数据实

体类呢?

这其中还是有一些差别的。

首先,数据实体类是轻量级的 structure ,一般仅包含数据字段,没有

什么操作方法,这比 DataTable 或者 DataRow 还是有一些性能上的优势

(在数据量不大时可以忽略不计);另一方面,数据实体类的操作相对

简单,不需要开发人员具备任何 ADO.NET 知识(其实就 DataTable 来

说,这也不算什么问题),点点属性就可以了。

不过,根据作者的实践来看,这两方面似乎还不足以使人转而使用

DataReader 方案,理由列举如下:

(1) 对于数据量较大的场合,可以采用分批读取的方式,这有点类似 DataGrid 的数据分页效果;

(2) 对于简单的数据,实体类还能应付,一旦涉及关联数据,就只能另外撰写方法了。而所有这些,在 DataSet 中是非常容易处理的(对于企业级应用,大部分情况都需要处理比较复杂的数据);

(3) DataTable “天生”就支持数据集合操作,这样的特性比“ 集合 ** + ** ** 实体 ** ”的混合模式( PetShop )更容易控制,也更自然;

(4) 实体类在声明时需要确定所有数据类型,当进行数据填充时,就需要 DataReader 再次关注实体所对应的数据类型,不能有丝毫差错!在这方面, DataTable 就显得非常方便,操作时只需要 一次类型关注 即可;

(5) DataSet 解决方案可以非常方便的支持序列化操作(如: Remoting , WebServices ),同时,与 XML 的关系更是亲密无比,这对于和其它系统的交互来说也是至关重要的。

**分析过一些技术和方案,相信读者朋友已有一些体会。值此收官之际,如果非要在这里提供一个“综上所述”,那作者的建议就非常明确: **

**_ _ **

在企业级应用开发中, 尽可能 的采用 ** DataSet ** ** ( ** ** DataTable / DataView ** ** ) ** ** + Cache Management ** 解决方案!

其它开发中,只在如下 ** 4 ** ** 种情况 ** 才考虑 使用 ** DataReader ** (就作者经验来说,大部分使用 DataReader 都属第 2 种情况):

(1) 对资源要求比较苛刻的场合,这里的资源主要指内存和数据库连接;

(2) 希望在读取数据库返回结果集时作自定义处理,例如:在读取一条记录后立刻终止处理,或者在读取时作计算操作。

_ (提示:这种情况类似于 XML _ _ 中的 SAX _ _ ( Simple API for XML _ _ )技术,无需一次性读入所有 XML _ _ 数据即可进行操作;相反的, DOM _ _ ( Document Object Model _ _ )则要求必须装载所有 XML _ _ 数据后才能开始操作( MSXML4.0 _ _ 已开始允许只读取 XML _ _ 文档部分数据即可开始操作,这是后话) ! _ _ ) _

_ _

(3) 只希望得到返回记录数或者返回记录的部分字段,如:

string GetNameByID(int nID) **// ** _ 根据员工 ID _ _ 返回员工姓名,这里只需要 _

_ // _ _ 读取姓名字段; _

_ (提示:这种情况一般可以通过执行特定的查询或存储过程直接解决) _

(4) 出于某些方面的考虑(例如: n-Tier 系统中严格区分各 Layer 间的职责),无法(或者禁止)通过数据库本身进行查询过滤,这时就只有使用 DataReader 在读取时进行过滤操作!

_ (提示:虽然 DataView _ _ 也能达到这种目的,但它的过滤前提是必须读取到所有返回数据,所以性能上不如 DataReader _ _ !) _


** 作者简介: ** ** **

“ 本文作者张雪峰 是 毕博全球开发中心 的高级开发工程师。他目前在中国上海 毕博全球开发中心 Core/EAI 部门工作,从事 .NET 技术的研究以及相关项目的开发。可以通过 [email protected] 与他联系。 ”


Published At
Categories with Web编程
Tagged with
comments powered by Disqus