1、XPO开发指南摘要 [引用] 2007-10-16 14:59:46| 分类: 数据库相关 | 标签: |字号大中小 订阅 一.XPO简介: XPO即eXpress Persistent Objects for .NET,现在这里介绍的版本是1.5。 XPO在应用程序代码和数据库之间扮演了一个中间层的角色,简单而言,就是将面向对象编程所建立的对象在数据库中做一个映射,使之和数据库中的表建立一一对应的关系。XPO现在的版本已经可以处理对象之间一对多,多对多等关系的处理,继承在数据库中的实现以及根据情况处理进行数据库的并发访问,提高系统的效率。 XPO最大的好处就是可以将应用
2、程序开发者从繁琐的数据库设计中解脱出来,专心建立业务对象系统,如何将这些对象映射到数据库中,这一切都可以交给XPO来自动处理了。 二.XPO的简单使用: XPO的使用十分简单,如果是应用系统的数据关系不复杂,对于应用开发人员而言,根本上可以不了解XPO太深入的技术,只需要在建立对象类过程中,遵循一定的规则就可以了。而且在使用过程中也根本可以不去关心数据库后台发生的事情,例如后台是什么数据库,表到底有多少等。 1.建立对象类: 首先是需要定义对象,一切的对象只需要继承于XPObject即可。 例如下面的代码就是建立一个Member的类,其中涉及到名字和年龄。 这个是一个最简单
3、的例子,在使用过程中根本不需要考虑数据库到底建立了没有,以及数据库建立在那里等。当然,如果在应用中需要了解这些信息,在后面的介绍中可以看到,其实XPO同样提供了十分丰富的函数来获取这些信息的。
using System;
using DevExpress.Xpo;
namespace testXPO
{
///
4、 public int iAge; public Member() { // // TODO: 在此处添加构造函数逻辑 // } } } 2.使用和保存这些对象的数据: 以下代码是定义一个Member,并且将这些数据保存起来的例子: Member m = new Member(); m.iAge = 15;
5、 m.strName = "testName"; m.Save(); 可以看到使用起来十分方便,一点也看不到数据库操作的影子。 3.获取对象的集合信息: 保存的信息如何全部获取呢?以下是个例子: foreach (Member m in new XPCollection(typeof(Member))) { lstResult.Items.Insert(0,"Age:" + m.iAge + "; Name:" + m.strName);
6、 }
假设将全部Member的信息显示在一个ListBox中。
小结:到此为止对于如何使用XPO应该有个很初步的了解了。
步骤大致如下:
1. 将DevExpress.XPO.dll引用进来;
2. 声明使用 using DevExpress.XPO;;
3. 需要数据保存的类则继承于XPObject;
4. 需要对外的信息则定义成字段即可,一切象一般创造一个类无异;
XPO到底做了些什么呢?
面对这么简单的代码,其实和数据库的互动已经全部由XPO自动帮你完成了。
1. 运行后会在当前目录下建立一个
7、件; 2. 打开这个数据文件可以发现有两个系统自动建立的表:XPDeletedObject和XPObjectType; 3. 另外还有就是对应类的表了,这里是Member表。 在MDB中的结构如下图所示: 到此为止我们已经可以用XPO来完成新建表,新建记录,返回全部记录这些传统的数据库操作了。虽然功能十分简单,但是可以大致了解XPO大致会为我们做些什么了,会给我们带来一些什么的方便了。 三.XPO的进一步使用: (一)对象关系的处理: XPO支持对象之间一对一,一对多和多对多的关系。 1.定义一对多的关系: 假设有一个Student的类和一个Class类是一对多的对
8、应关系,一个学生可以有多个Class的信息。
类图关系如下:
Class类对应的代码:
using System;
using DevExpress.Xpo;
namespace testXPO
{
///
9、 public string Name;
public int Credit;
public Class()
{
//
// TODO: 在此处添加构造函数逻辑
//
}
}
}
Student类对应的代码
using System;
using DevExpress.Xpo;
namespace testXPO
{
///
10、nt 的摘要说明。 /// public class Student : XPObject { public string Name; public int Age; [Association("StudentClasses", typeof(Class))] public XPCollection Classes { get { return GetCollection("Classes"); } } public Student()
11、 { // // TODO: 在此处添加构造函数逻辑 // } } } 其中Association属性部分就是关键定义这个一对多关系的代码。 以下代码是添加记录的代码,假设添加5个学生,每个学生有不同的三门课程。 for (int i=1;i<6;i++) { Student sd = new Student(); sd.Na
12、me= "Student" + i.ToString(); sd.Age = 2*i; Class cls1 = new Class(); Class cls2 = new Class(); Class cls3 = new Class(); cls1.Name = sd.Name + "英语"; cls1.Credit = 5 * sd.Age;
13、 sd.Classes.Add(cls1); cls2.Name = sd.Name + "数学"; cls2.Credit = 6 * sd.Age; sd.Classes.Add(cls2); cls3.Name = sd.Name + "语文"; cls3.Credit = 7 * sd.Age; sd.Classes.Add(cls3);
14、 sd.Save(); } 可以看出: Class数据不需要单独保存,在后面总体对Student做一个保存,XPO会自动完成CLASS数据的保存;对于一个学生对应几个CLASS,每个CLASS的实体需要存在,例如这里就新建了cls1-cls3三个不同的实体,否则保存到数据库中,之后最后一个实体有效。 那么在数据库中发生了什么事情呢: CLASS和STUDENT两个表自动生成了,且数据也保存了,之间的关系也建立了,如下图: 以下是对这种关系的数据进行浏览,例如想获取学分是5的信息: XPCollection c
15、lsAll = new XPCollection(typeof(Class), new BinaryOperator("Credit", 5, BinaryOperatorType.Equal)); foreach (Class cls in clsAll) { lstResult.Items.Insert(0,"Student's Name: " + cls.Student.Name + ";Student's Age:" + cls.Student.Age + "; Class's Name:" + cls.Name);
16、 } 由此可见XPCollection可以作为对象的集合来使用,且对应回数据库中的记录概念,当然这种对象的集合比数据表的记录灵活很多。 小结:对于关系,一方的关系定义象Student中: [Association("StudentClasses", typeof(Class))] public XPCollection Classes { get { return GetCollection("Classes"); } } 而多方中的关系定义象Class中: [Association("StudentCla
17、sses")]
public Student Student;
也就是说一方定义需要集合类型(多),而多方定义则只须定义回一方的类。
注意:Association中定义的关系名字是相同的。
(二)对象继承的处理:
继承的例子:例如学校中有Staff和Dean类,Dean从Staff继承过来,当你查找Staff的数据时,Dean的数据也会获取出来的。
定义Staff的代码:
using System;
using DevExpress.Xpo;
namespace testXPO
{
///
18、// Staff 的摘要说明。 /// public class Staff : XPObject { public string Name; public int Age; [Association("DeanStaffs")] public Dean Dean = null; public Staff() { // // TODO: 在此处添加构造函数逻辑
19、 //
}
}
}
定义Dean的代码:
using System;
using DevExpress.Xpo;
namespace testXPO
{
///
20、 public XPCollection Staffs { get { return GetCollection("Staffs"); } } public Dean() { // // TODO: 在此处添加构造函数逻辑 // } } } 可见继承关系除了面向对象本身定义了的继承外,还需要声明之间的关系,这个关系就是对应到数据库中的关系了。
21、 以下是生成数据的代码: for (int i=1;i<11;i++) { Dean d = new Dean(); d.Name = "Dean" + i.ToString(); d.Age = 100 * i; d.Department = "Dean's Department" + i.ToString(); d.Save(); }
22、 for (int j=1;j<20;j++) { Staff s = new Staff(); s.Name = "Staff" + j.ToString(); s.Age = j; s.Save(); } 前面部分生成Dean的数据,后面生成Staff的数据,那么数据库里面发生了什么变化呢: 生成的数据如下图: 这里可以看到Dean中的OID不再是自
23、动生成的了,而是对应Staff中的OID。 小结: 对于父类,需要声明关系如Staff: [Association("DeanStaffs", typeof(Staff))] public XPCollection Staffs { get { return GetCollection("Staffs"); } } 对于子类,需要声明关系如Dean: [Association("DeanStaffs")] public Dean Dean = nul
24、l; (三)XPO中Session的使用: XPO的缺省设置是使用MS Access OLEDB,并且使用在当前路径下的MDB,如果应用需要特别指明数据库则需要用到Session了。 只需要在对象构造时将Session作为参数传递进去就可以了。 例如: public class Member : XPObject { public string strName; public int iAge; public Member(Session session) : base (ses
25、sion) { // // TODO: 在此处添加构造函数逻辑 // } } 创建Session则如下面的代码: Session session2 = new Session(); session2.AutoCreateOptions = AutoCreateOptions.SchemaOnly; session2.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0; Use
26、r ID=Admin;Data source=SessionExample2_cs.mdb;Mode=Share Deny None;"; session2.Connect(); 实际项目中,关于Session的设定可以放在Global.asax文件中操作。如下例 Global.asax <%@ Application Language="C#" %> (四)XPO中查询数据: 对于查询,就是指定一定的条件获取一个数据集合。在XPO中,返回结果的集合用XPCollection作统一处理,而条件查询的条件设置,则通过 BinaryOperator来指定。 例如:要
32、查询出生日期在”01/02/1960”年之前的客户资料: new XPCollection(typeof(Customer), new BinaryOperator("BirthDate", new DateTime(1960, 1, 2), BinaryOperatorType.Less)) 如果条件是组合的,例如:要查询出生日期在”01/02/1960”年之前的且地址是第十大街的顾客的资料: GroupOperator criteria = new GroupOperator(); criteria.Operands.Add(new BinaryOperat
33、or("BirthDate", new DateTime(1960, 1, 2), BinaryOperatorType.Less)); criteria.Operands.Add(new BinaryOperator("Address.Street", "10'th Avenue")); new XPCollection(typeof(Customer), criteria) (五)XPO中的事务处理: XPO提供了类似于Microsoft ADO.NET中的事务处理,你可以在Session中使用Begin,Commit或者Rollback的方法来完成处理。在当前的版本中,事务
34、处理的嵌套并不支持。 以下代码是事务处理的例子: class Account: XPObject { public double Amount = 0; protected override void BeforeSave() { base.BeforeSave(); if (Amount < 0) { throw new Exception("Negative amount"); }
35、 } } void TransferAmount(double amount) { Account account = new Account(); Session.DefaultSession.BeginTransaction(); try { account.Amount = amount; account.Save(); Session.DefaultSession.CommitTransaction(
36、); } catch (Exception e) { Session.DefaultSession.RollbackTransaction(); account.Reload(); } } (六)XPO中返回记录的分页处理: 在XPO中,除了XPCollection外,还有一个XPCursor提供了一个获取返回记录的另外一种方式。和XPCollection返回全部的满足条件的集合不同,XPCursor根据XPCursor.PageSize的设置依次返回满足条
37、件的每页数据。
XPCursor这种特性在处理数据量比较大的表是十分有用的,可以减少每次内存的使用量和减少返回的时间。
当然,每次翻页则需要重新获取数据。
(七)XPO中对结构体的支持:
从1.5版本开始,XPO将支持结构的特性。
例如定义一个圆的类,圆心是一个结构体,代码如下:
using System;
using DevExpress.Xpo;
namespace testXPO
{
///
38、 Point { [Persistent("Abscissa")] public int X; public int Y; } public class Circle : XPObject { public string Name = ""; [Persistent("Location")] public Point Center; public Circle() {
39、 // // TODO: 在此处添加构造函数逻辑 // } } } 生成数据的代码如下: for (int i=1;i<11;i++) { Circle c = new Circle(); c.Name = "Circle" + i.ToString(); c.Center.X = 100 + i;
40、 c.Center.Y = 10 + i; c.Save(); } 看看数据库中表的存储情况: 小结:XPO对结构体已经支持,并且将其平面化到同一个表中。 ?? 不知道对结构体嵌套的是否支持?有待证实 对于结构体相关数据的查询也并不复杂,例如下面: new XPCollection(typeof(Shape), new BinaryOperator("Position.X", 1)) 关于 DevExpress XPO 的介绍[引用] 2007-10-22 11:03:37| 分类: 数据库
41、相关 | 标签: |字号大中小 订阅 著名的Delphi第三方控件开发商DevExpress公司新近公布了其在.NET的新型数据应用工具eXpress Persistent Object v.1.5 for .Net,其发行版本的代号为XPO,是一款专门用于.NET环境下的数据库应用开发工具。DevExpress的开发能力已为广大程序员所熟知,正是基于对该公司开发工具的信任,我想此款控件个头虽然不是很大,但其开发能力应该是有所保证的。在其应用过程当中,有一些心得,不敢独享,现整理成文,供大家参考学习。由于水平有限,错误之处再所难免,欢迎批评指正并交流。可与我Email联系。 e
42、Xpress Persistent Objects for .NET为软件的对象与关系数据库之间提供了一个强大的桥梁作用,可以为开发者提供相当大的自由度来创建真实的商业对象,而不必去考虑处理如何将其映射到数据表中那些繁复的细节处理。eXpress Persistent Objects for .NET完整地从开发者角度抽象了数据库层,让开发人员可以完全沉浸在面向对象的设计氛围里。通过XPO,开发人员建立的应用程序可以很好地工作在各个不同的数据库系统之下(不久即将支持MSAccess和MSSQL数据库系统,难道现在不支持么?呵呵),而不用更改一点儿代码。 XPO非常容易上手。如果您看过Mi
43、crosoft.Visual.Studio.NET.2003所带的例子Duwamish7,在其中的Common模块当中,一定会被其数据表映射的代码段看个头晕脑胀,而且觉得微软的程序员难道会这么机械么?而从其代码来看,却又不得不承认,那帮子程序员的确是够机械的。然而如果有了XPO,你将完全可以从那样机械的代码当中解放出来。 开发人员所需要做的仅仅是定义一个持久性的对象类,XPO.NET会自动为其生成数据库。XPO.NET会透明(在DevExpress公司的介绍当中,Transparently这个词频繁地出现,也许正是其强调的一个亮点之处吧)的处理类与对象实例之间的关系,不必为灵活性而牺牲其
44、易用性。如果想更多地控制O/R映射关系,可以使用XPO内建的属性提供的附加映射信息来满足任何商业需求。 利用XPO.NET可以从对象模型直接进行数据库应用程序的开发,不必在表、列、关系及约束等方面花费更多的时间,而把主要的精力放在代码的编写上,它使您把主要的精力集中在应用需求等问题上,再也不必要为数据库的瓶颈等问题而头疼了。总之,是好处大大、功能强强的,套用一句DevExpress公司的宣传口号是: Total Control, Flexibility and Power Bridging the Gap Between the Object World and Relationa
45、l Databases. 1、eXpress.Persistent.Object.v.1.5的新特性 映射已存在的数据库。XPBaseObject做为基类可为持久性对象提供服务。 支持MSSQL7.0(^_^,这也算一个新特性?呵呵)。 页面级收集器。PageSelector类允许对一个源容器进行页面管理。 设计期的页面管理。XPPageSelector组件允许在设计时段指定一个页面容器做为数据源,并绑定到用户界面。 容器内容过滤。XPCollection.Filter属性允许过滤出已存在的容器内容,并可获取匹配过滤标准的子容器项目。 容器内容排序和过滤。非持久性
46、属性可用于过滤和排序XPCollection容器的内容。 排序与过滤选项。XPCollection.CaseSensitive属性可控制容器成员的大小写。 新的标准运算。AggregateOperand允许通过Aggregate.Sum,Aggregate.Count,Aggregate.Min和Aggregate.Max操作选项进行运算。 支持值对象。 值与类型转换。借助于ValueConverter和ValueConverterAttribute类可以实现数据库值与持久性属性之间的双向转换。 数据库视图的映射。持久性对象现可以映射到数据库视图。 持久性空值。空值可通
47、过NullValueAttribute被存储在数据库中。 自定义数据库类型。利用持久性属性或字段映射,利用DbTypeAttribute可明确标识出列的类型。 跟踪容器内容的更改。可通过CollectionChanged事件跟踪容器内容的更改。 性能的提高。当对象被加载时,ExplicitLoadingAttribute要帮助优化数据库查询性能。 XPBaseObject。XPBaseObject现可支持IEditableObject。可通过此接口控制对象的改变。 XPBaseObject。XPBaseObject现拥有一个虚拟的AfterConstruction方法允许实
48、现逻辑创建自主对象。 XPCollection。XPCollection扩展CollectionChanged事件,提供在容器操作过程中执行自定义动作。 2、XPO如何工作 面向对象的应用程序设计与开发为当前的复杂应用开发提供了一个高性能与多产的手段,提高了代码重用的机会,以及当最终用户需求发生变化时更高的灵活性。 当创建一个数据库应用时,开发人员看起来总是被迫与数据表、视图、数据字段对象打交道,而不是直接处理商业对象。这种关系数据库对象领域的差距现象类似于ADO.NET和特定领域内的商业对象的差别,对开发人员来讲,同样是一极大的挑战。 Visual Studio
49、NET试图通过类型安全数据集来解决这个问题:一个开发人员可以拾取一个数据表并且生成一个类型安全的数据集类,使该类看上去更类似于一个事务域中的商业对象,这种机制被用于实现持久性商业对象,尽管看来此类对象更像是面向数据的一个结构。 那么有没有一种方法可以映射你设计良好的商业对象模型到关系数据库而不必处理数据表与字段呢?也许您已经猜到这个答案了。通过XPO就要以实现这样的工作。XPO从另外一个不同的角度试图来解决这个问题——通过对商业对象世界的透视。 来看一个小例子。在一个销售管理应用程序中,一个联系人的类是如下来表示的: public class Contact { publ
50、ic string FirstName; public string LastName; public string PhoneNumber; public string Email; } 很显然,在销售管理应用系统当中所有的联系人都应该保存在数据库中,因此Contact必然是一个持久化对象。要想将其持久化,其实非常之简单,所需要做的只是将其从XPObject中进行继承: using DevExpress.Xpo; ... public class Contact: XPObject { public string FirstName; public strin
©2010-2025 宁波自信网络信息技术有限公司 版权所有
客服电话:4009-655-100 投诉/维权电话:18658249818