剖析 .Net 下的数据访问层技术(二)
2024-07-10 13:03:39
供稿:网友
其它
结束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!)