欢迎光临
我们一直在努力

用ObjectSpaces重建IBuySpy的数据访问层-.NET教程,Asp.Net开发

建站超值云服务器,限时71元/月

objectspaces这个orm框架可能已经被大家听过n次了,它诞生很早,但开发周期拖了很长,虽然很早它的测试版本就已经有人使用了,但只到.net framework 1.2才计划正式将它包含其中,并放在了object.data.objectspaces这个namespace中。
  
  
  
  objectspaces的流传版本也是甚多,被很多人研究过的一个eap(early adopter preview)版的版本号是1.0.1081,我在gotdotnet.com里面看过一个1.0.3328.4的版本做的东西,这里用的这个objectspaces是现在大家普遍使用的.net framework 1.2 alpha测试版里面带的,版本号同.net framework保持一致,1.2.30703.27。
  
  
  
  从版本号的变更就可以看出,objectspaces从开始到现在变化很大。上面提到的三个版本都各有差别,而且差别不小。现在最新的这个版本我想应该和最终版本差别不会很大了。我以前的一篇文章就是基于eap版本的,比现在的简单不少。
  
  
  
  进入正题:在ibuyspy的架构中,实际上是没有bll(商业逻辑层)的,甚至没有创建entity class,数据通过dal(数据访问层)从数据库中获得,然后将dataset或者datareader直接从dal传递给构成ibuyspy页面的module的ascx文件,再直接绑定到datalist之类的web control上。
  
  
  
  我们这里将ibuyspy的announcement模块的dal用objectspaces重新写过:
  
  
  
  一、先来看看ibuyspy原来的announcements模块
  
  
  
  dal:announcementsdb.cs文件
  
  界面控件页面:用于显示的announcements.ascx控件和用于新增修改的editannouncements.aspx页面
  
  
  
  里面都是最最标准的写法,没什么讲的。
  
  
  
  二、entity class
  
  
  
  新创建一个announcement类和一个announcementcollection集合类,也没什么讲的。
  
  
  
  三、建立objectspaces的rsd、osd、msd
  
  
  
  objectspaces的核心就是用来描述schema的三个xml文件:
  
  一个描述数据库表结构的relational schema definition,一个描述实体类结构的object schema definition,和一个描述表结构和实体类映射关系的mapping schema definition。
  
  用objectspace最主要(也是最烦人)的工作就是把这三个schema写出来。eap版里面还只有一个xml文件要写,现在要写三个了l。
  
  
  
  announcementrsd.xml
  
  announcementosd.xml
  
  announcementmsd.xml
  
  
  
  四、重写dal
  
  
  
  创建一个新的类文件announcementosdb.cs,包含一个新的类announcementosdb,里面的方法签名对照着ibuyspy原本的announcementdb类就行了。原本的announcementdb是用ado.net,返回dataset、datareader,我们的announcementosdb就用objectspaces,返回实体集合类或实体类。
  
  
  
  根据moduleid返回announcement集合:
  
  public announcementcollection getannouncements(int moduleid)
  
   {
  
   objectspace os = new objectspace(_smapfilepath, _conn);
  
   // 条件是moduleid等于参数moduleid,expiredate大于当前时间
  
   objectquery query = new objectquery(typeof(announcement), “moduleid = ” + moduleid.tostring() + ” and expiredate > #” + datetime.now.tostring() + “#”);
  
   // 取数据
  
   objectreader reader = os.getobjectreader(query);
  
  
  
   announcementcollection result = new announcementcollection();
  
   // 从objectreader中取值不需要另外造型
  
   foreach (announcement ann in reader)
  
   {
  
   result.add(ann);
  
   }
  
  
  
   return result;
  
   }
  
  
  
  根据参数返回一个announcement:
  
   public announcement getsingleannouncement(int itemid)
  
   {
  
   objectspace os = new objectspace(_smapfilepath, _conn);
  
   objectquery query = new objectquery(typeof(announcement), “itemid = ” + itemid.tostring());
  
   return (announcement) os.getobject(query);
  
   }
  
  
  
  根据参数删除一个announcement:
  
   public void deleteannouncement(int itemid)
  
   {
  
   objectspace os = new objectspace(_smapfilepath, _conn);
  
   objectquery query = new objectquery(typeof(announcement), “itemid = ” + itemid.tostring());
  
   announcement ann = (announcement) os.getobject(query);
  
   os.markfordeletion(ann);
  
   os.persistchanges(ann);
  
   }
  
  
  
  新增一个announcement:
  
   public void addannouncement(int moduleid, int itemid, string username, string title, datetime expiredate, string description, string morelink, string mobilemorelink)
  
   {
  
   announcement ann = new announcement();
  
   ann.setmoduleid(moduleid);
  
   ann.setitemid(-1);
  
   ann.createdbyuser = username;
  
   ann.createddate = datetime.now;
  
   …
  
  
  
   objectspace os = new objectspace(_smapfilepath, _conn);
  
   os.starttracking(ann, initialstate.inserted);
  
   os.persistchanges(ann);
  
   }
  
  
  
  修改一个announcement:
  
   public void updateannouncement(int moduleid, int itemid, string username, string title, datetime expiredate, string description, string morelink, string mobilemorelink)
  
   {
  
   objectspace os = new objectspace(_smapfilepath, _conn);
  
   objectquery query = new objectquery(typeof(announcement), “itemid = ” + itemid.tostring());
  
   announcement ann = (announcement) os.getobject(query);
  
  
  
   ann.createdbyuser = username;
  
   ann.title = title;
  
   …
  
  
  
   os.persistchanges(ann);
  
   }
  
  
  
  五、最后修改界面层
  
  
  
  原本界面层是把announcementdb返回的dataset绑定到web control上,只要改成将announcementosdb返回的实体集合类绑定到web control上就可以了,改动量很少很少。
  
  
  
  比如:
  
  原本将数据取出并绑定的代码(在announcemenets.ascx.cs中):
  
  announcementsdb announcements = new announcementsdb();
  
  mydatalist.datasource = announcements.getannouncements(moduleid);
  
  mydatalist.databind();
  
  只要将第一句改成:
  
  announcementosdb announcements = new announcementosdb();
  
  实际上就是改从哪个dal取数据就ok了。
  
  
  
  六、讲讲objectspaces
  
  
  
  objectspaces的架构是这样的:
  
  objectspace类管理数据映射,它负责(隐形的通过objectengine)从数据源(idbconnection或者objectsources)取数据和将数据更新回数据源(更新时会自动隐形启用transaction)。它通过objectspace.getobject()返回单个对象,通过objectspace.getobjectset()返回objectset对象(这个对象类似于dataset,表示一组数据对象),通过objectspace.getobjectreader()返回objectreader对象(这个对象类似于datareader,是一个快速的forward-only的数据对象读取器)。它通过内含的objectcontext来维护数据对象的原始值和监视数据对象的值的修改。
  
  
  
  我上面的代码演示目的是为了展示objectspaces,并没有完整的给ibuyspy加一个bll。我也没有演示数据之间的relations,objectspaces可以支持非常丰富的relations,onetoone、manytomany、onetomany等等,而且也提供了lazyloading(在真正需要使用relation的数据的时候才真正去取这些数据)。
  
  
  
  不过如果你也试着用objectspaces来重建你的项目中的dal,我不知道你的感觉会不会和我一样,那就是“比现在更麻烦…”。比如,不支持存储过程(难道支持而文档里面不提一句吗?eap版本还支持的),手工写rsd、osd、msd太繁琐了(pdc2003上出现过一个mapper utility,希望whidbey会提供自动化工具),灵活性降低不少(所有orm框架的问题)。

赞(0)
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com 特别注意:本站所有转载文章言论不代表本站观点! 本站所提供的图片等素材,版权归原作者所有,如需使用,请与原作者联系。未经允许不得转载:IDC资讯中心 » 用ObjectSpaces重建IBuySpy的数据访问层-.NET教程,Asp.Net开发
分享到: 更多 (0)