帝国软件
  设为首页 加入收藏 关于我们
 
解密帝国网站管理系统
栏 目:
 
您的位置:首页 > 技术文档 > ASP.NET编程 >
用ObjectSpaces重建IBuySpy的数据访问层
作者:Kaneboy 发布时间:2005-03-12 来源:ASPCOOL
     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框架的问题)。
  
  Kaneboy's blog :http://blog.joycode.com/kaneboy/
  

  
评论】【加入收藏夹】【 】【打印】【关闭
※ 相关链接
 ·使用Observer模式  (2005-03-12)

   栏目导行
  PHP编程
  ASP编程
  ASP.NET编程
  JAVA编程
   站点最新
·致合作伙伴的欢迎信
·媒体报道
·帝国软件合作伙伴计划协议
·放眼未来 帝国近期将有重大举措!
·PHPWind6.3.2版通行证发布
·帝国备份王2008版正式发布
·帝国备份王2008版发布
·phpcms2007转帝国CMS5.0程序发布
·dedecms5.1转帝国CMS5.0程序发布
·帝国网站管理系统V5.0商业购买说明
   类别最新
·ASP.NET中为DataGrid添加合计字段
·.text urlRewrite介绍
·利用 ASP.NET 的内置功能抵御 Web
·ASP.NET Cache
·用 WebClient.UploadData 方法 上载
·ASP.NET 程序设计-序
·什么是客户端/伺服端(Client/Serve
·因特网应用程序的开发
·网页的种类
·.NET Framework-Microsoft Visual
 
关于帝国 | 广告服务 | 联系我们 | 程序开发 | 网站地图 | 留言板 帝国网站管理系统