用ObjectSpaces重建IBuySpy的数据访问层
点击次数:21 次 发布日期:2008-11-26 12:31:12 作者:源代码网
|
源代码网推荐 源代码网推荐 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/ 源代码网推荐 源代码网推荐 源代码网推荐 做人要厚道,请注明转自酷网动力(www.ASPCOOL.COM)。 源代码网推荐 源代码网供稿. |
