XPO学习

XPO 这是我从网站上得到的资料,后边是我在使用XPO时所用到的一些知识,包括 XPLiteObject的AutoSaveOnEndEdit属性 ContainsOperator的使用 XPCollection复杂查询 XPView可以增加属性 XPQuery的用法 UnitOfWork的FindObject的用法 Session.Evaluate的计算功能 基本概念 普通类:

XPO

这是我从网站上得到的资料,后边是我在使用XPO时所用到的一些知识,包括

XPLiteObject的AutoSaveOnEndEdit属性

ContainsOperator的使用

XPCollection复杂查询

XPView可以增加属性

XPQuery的用法

UnitOfWork的FindObject的用法

Session.Evaluate的计算功能

 

基本概念

   普通类:就是一个简单的定义的类。

   持久化类:可以把类的实例中的数据透时的保存到数据库中的类。

什么是XPO

  XPO是由大名鼎鼎的DevExpress提供的一种商业的ORM工具。

 从概念上来说XPO是一种简单的对象映射技术,是一种把一个普通类变成持久化类的技术。也就是让一个普通的类和数据库中的一个表对应。把表中的字段和类中的字段对应,你可以透明的将一条记录直接保存到数据库,而不需要和ADO.net打交道。

  下面是XPO中的类层次结构

这些类到底有啥作用呢?

这些类提供了将一个类的自身的数据保存到数据库中的所有功能。只要你继承其中一个类,你的类就马上变成了一个可以持久化的类了。也就是具有了将类自己的数据保存到数据库的能力。

看看顶层的XPBaseObject对象,他是XPO持久类中的基类,为其它的类提供了一个基本实现。当你的类继承XPBaseObject,你必须为你的类指定一个主键的字段。他不支持延后删除技术。

XPLiteObject 基本和基类没什么区别 但是他不支持数据库并发中的锁定,和延后删除的技术。

XPCustomeObject 和基类一样,但是他支持并发数据库中的锁定,同时他也和基类要提供自定义主键的。他是支持延后删除技术)

XPObject 这个应该是最常用的,他提供自已的OID字段,因而如果你的类继承于它,就不需要为提供主键。(最全的类了,支持延后删除,支持锁定)

什么叫延后删除:一个持久化类,他是和数据库中的一个记录对应的,当你执行一个删除一个持久化类的动作的时候,XPO不会马上就去在数据库上执行真正的数据删除,而是将这条记录标记为删除,而且已经后不会在读取他。。当你要真正删除时,可以调用Session.PurgeDeletedObjects()来完全删除这些标记的记录

 

 

 

类名

延后删除

数据锁定

提供OID字段

XPBaseObject

不支持

支持

不提供

XPLiteObject

不支持

不支持

不提供

XPCustomObject

支持

支持

不提供

XPObject

支持

支持

提供

 

XPO复合主键

You need to create a struct (Structure in VB.NET), which represents a multi-column key and an XPBaseObject derived class with a Key property definition. Here is the code for mapping to the Sales table in the MS SQL Pubs sample database:

using DevExpress.Xpo;

public struct SalesKey {
    [Persistent("stor_id")]
    public string StorId;
    [Persistent("ord_num")]
    public string OrdNum;
    [Persistent("title_id")]
    public string TitleId;
}

[MapTo("sales"), OptimisticLocking(false)]
public class Sales : XPBaseObject {
    [Key, Persistent]
    public SalesKey Key;

    [Persistent("payterms")]
    public string PayTerms;
    ... // other properties
}

 

 

 

 

 

 

C#中自定义属性的例子

自定义属性的作用

      有时候我们需要给一个类或者类中的成员加上一些属性或者附加信息,让类或者变量的功能更明确可控制的细粒度更高,打个简单的比方:数据库里面的一张表,表中的每一个字段都有很多属性,如是否主键,默认值,注释信息等等,我们在编写实体类的时候,如何表示这些信息呢?通过自定义属性可以实现。

自定义属性的实现步骤

      我说了不算,权威说了算:

1.       声明一个类,并将 AttributeUsageAttribute 属性应用到该类中。类的名称即为新属性的名称

2.       声明该类从 System.Attribute 继承:

3.       定义 Private 字段来存储属性值:

4.       需要时,请为属性创建构造函数:

5.       为属性 (Attribute) 定义方法、字段和属性 (Property):

 实例一个:

属性类(和相关枚举)

/// <summary>
$yQ/S2?g0    /// 数据库字段的用途。ITPUB个人空间 }R h­r P'VB
    /// </summary>
E#j i#Y | Wuf0    public enum EnumDBFieldUsageITPUB个人空间(X­z-w8i&L5zd\0b Jt?
    {
)K­W"l}$Xl0        /// <summary>ITPUB个人空间(O:H i)G.R
        /// 未定义。ITPUB个人空间1K G­v)P]tjqq
        /// </summary>
Q}`)m Ie8k1\;[,^0        None = 0x00,
­_/uZ


`S1_0        /// <summary>
2v^|t l$K&f
z0        /// 用于主键。ITPUB个人空间
eG:u3`!K3n;B4W
        /// </summary>ITPUB个人空间4u-Y%WW!Pb
        PrimaryKey = 0x01,ITPUB个人空间E5DA#fE7V|‑u!b
        /// <summary>ITPUB个人空间WZ}g0aG­q[1]m\0t
F­`
        /// 用于唯一键。ITPUB个人空间"v }‑u;D4[ z8P e9PS2N
        /// </summary>
/k uVS!u't‑X4b$j
l0        UniqueKey = 0x02,ITPUB个人空间g9xM7F_i
        /// <summary>
Y r9Q8MVu0        /// 由系统控制该字段的值。ITPUB个人空间fD:D1| U
        /// </summary>
uY ]0T5nV‑B"^0        BySystem = 0x04

^vpAV
Q#u0    }
/d‑i/@7Cp ||!Al0ITPUB个人空间$R.h8]%_0Pk U
    [AttributeUsage(AttributeTargets.Property, Inherited = true)]
K/p^!@[1]_/jLd5C0    public class DBFieldAttribute:Attribute
i h-fN'T
{!l zn
M0    {
qF H oZ1j0        EnumDBFieldUsage m_usage;
H I-Yi'l0        string m_strFieldName;ITPUB个人空间‑sO;ex;ns-^4u
        string m_strDescription;
Wx6K O
k2\.G0        object m_defaultValue;ITPUB个人空间k:~d)d{Mw'?
}
ITPUB个人空间J |$@{"ZHix
        public DBFieldAttribute(string strFieldName,object defaultValue,EnumDBFieldUsage usage,string strDescription)
"f.z
Ms@"Fk[1]@0        {ITPUB个人空间 T3c.WV!z!{2s+U8t
            m_strFieldName = strFieldName;

F$E`n$}d0            m_defaultValue = defaultValue;
‑|'Q2l5{)G]1h:]­Nk"z}0            m_usage = usage;ITPUB个人空间)}Lo;i2k
            m_strDescription = strDescription;
z‑n~%F
j*C.AZ0        }
[jU P&qg:h
]u0T0
Gh _(eLr0        public DBFieldAttribute(string fieldName) : this(fieldName,null, EnumDBFieldUsage.None,null)
Yq&\a9M‑RQ0        { }ITPUB个人空间 ]9{@_(G
ITPUB个人空间x]7^H!B)H-Y
        public DBFieldAttribute(string fieldName, EnumDBFieldUsage usage) : this(fieldName, null,usage, null)ITPUB个人空间 Nd­b ^3}H)S
        { }
5ti\$WX Kn0
]1I HJ f"ZC‑I0        
#I"UzLi h1c6QHy0        // 获取该成员映射的数据库字段名称。ITPUB个人空间M:S"n I
a*H
x!t
        public string FieldNameITPUB个人空间O
Wc$r@ [Re"T
        {ITPUB个人空间dY
I1cv
Z
}
            get
V$P7L&]Y!N0            {ITPUB个人空间7r7{4CE7n-Ga
                return m_strFieldName;ITPUB个人空间 {(a}8v;sp
            }ITPUB个人空间 z|"ZA;e*b
            set
Z3X/b)aG*GcB p0            {
1i1q:@&D-p
j.xhJ!O
?3]0                m_strFieldName = value;

v­| P7?:j&v9f,{0            }
?
g"U‑C%I6~k5EL0        }
%M
i)p4X^ f.G0ITPUB个人空间 Pq*g+fi b
        // 获取该字段的默认值
2B8Ab+f[1]N2A[1]| ] m0        public object DefaultValue
!Wo;G7dc0        {
_/@%L"s"d(\%`,O0            getITPUB个人空间9I­M w | a Vz1o+^D
            {
­Js&{O1t:w#T x D ?*@0                return m_defaultValue;
*W+y&L Ui$ZL'COs&v0            }ITPUB个人空间@L)V‑z#rY0I1S
            set 
(u‑w*X+`I%Q |0            {ITPUB个人空间:L
@0hgnej
                m_defaultValue = value;
-vM9y[1]a8C;H
D Vj0            }ITPUB个人空间#D+S9he*ic:o'S(H
        }
N @ ]5Tnf0    }

此代码说明了如何制作自定义属性类。其实跟一般的类的区别就是此类继承自Attribute,加上AttributeUsage是属性上的属性,是可选的。

 

数据访问层实体类:

class DalObj
N;x%k


A^0Mb+@0    {
0]/U‑o1a0er0        string m_strTableName;
ctRDta0        int m_nID;ITPUB个人空间i[1]Yh~ y t)Q e!Y
        string m_strName;
E5b K,HI.N!~!]#g#C0        string m_password;
4{(T(k
C%vOw0ITPUB个人空间I V,|b)Dc"D.J
        public DalObj(string strTableName)
D`A U ckC0        {ITPUB个人空间vPF}P
I
            m_strTableName = strTableName;
CQ'Q3ki5X0        }ITPUB个人空间5b.p‑~#i+O

8m `x;O%a0        [DBField("id",EnumDBFieldUsage.PrimaryKey)]ITPUB个人空间 k4f[1]l,S0H C1AE
        public int ID
,j?%y C!v t-BTO8r0        {
E$q2Z M@)WL7d8b }0            get { return m_nID; }ITPUB个人空间0E‑UF[1]AG
Yyx*h
            set { m_nID = value; }
)e7s5v(J5o­B E0        }ITPUB个人空间.X J4L&d:o)G7P5R2?

;M(p|d9j0        [DBField("name",DefaultValue="游客")]
Ao]7N!z R#V2]‑a0        public string NameITPUB个人空间#yT#E+n l-uG:ODR r*}‑b
        {ITPUB个人空间 N$q|
W)i0D
Q:T5x#z&G
            get { return m_strName; }
x)b/t w K2DDI'J Cv*T0            set { m_strName = value; }ITPUB个人空间.B
VrcQ2|
        }ITPUB个人空间wd0NF/m `

.\@­Zf[1]~q0        [DBField("pwd")]ITPUB个人空间q%c4K [$sx
v[1]X
        public string PassWordITPUB个人空间&g5u1hU5U-v y%H
        {
I7M"R.oqt-u0            get { return m_password; }ITPUB个人空间FWk@M Z
            set { m_password = value; }ITPUB个人空间-n0C5~/S)}4`t9kps
        }ITPUB个人空间[1][^ _
^"hS
    }

 

此代码说明了如何使用自定义的属性。有两点需要注意的地方

第一:类名可以跟自定义的类名一样,也可以加上或减去后面的Attribute,本例子中就是使用的时候跟自定义的类名减少了“Attribute”。

第二:属性参数填写方法,如果自定义属性类(例子中DBFieldAttribute)自己的构造函数带参数,那么这些参数是必选的,可以重载构造函数以满足不同组合,必选参数填完之后,可以继续给自定义属性类中的公共成员带命名地赋值,如例子中的DefaultValue="游客" 一句就是命名参数。

遍历自定义属性的代码:

            DalObj dalObj = new DalObj("users");ITPUB个人空间3?W^1n t#v}
            StringBuilder sb = new StringBuilder();ITPUB个人空间9M3R.^q2xQD


F
            foreach (PropertyInfo proInfo in dalObj.GetType().GetProperties())ITPUB个人空间$X}c
k zh
            {ITPUB个人空间L
c,Qj!B
                object[] attrs = proInfo.GetCustomAttributes(typeof(DBFieldAttribute), true);ITPUB个人空间{­\[1]bo[1]Y4?e‑ZS
              if (attrs.Length == 1)ITPUB个人空间wj1AMs‑^ H
              {ITPUB个人空间4CU8X:E e
T
                  DBFieldAttribute attr = (DBFieldAttribute)attrs[0];ITPUB个人空间%RY N,^,}­ba3_
                  sb.Append(attr.FieldName + ":" + (attr.DefaultValue == null ? "null" : attr.DefaultValue.ToString()) + "\r\n");
EUK3r+` U_0              }ITPUB个人空间&{*_Z-c-@Qw5|
            }ITPUB个人空间v5[*HLJ1A
s;G6Ug
            MessageBox.Show(sb.ToString()); 

此代码说明了如何检索自定义属性的值,主要用到了GetCustomAttributes来获取属性值。

 

 

 

XPO对Attribute的总结:

              应该看到,整个XPO框架中,Attribute使用的相当频繁,可以列出常用的:

            

         [Aggregated]   没有参数

            作用于a property or a field,并且只能是持久类的引用或者XPCollection.

            实现两个持久类的级联删除的功能。

       

[Association("PersonAddresses", typeof (Address))]

    作用于a property or a field

    实现两个持久类的级联关系

    参数:1、关联的名称;2、关联的持久类类型(但引用指明持久类型时,可以省略)

        

         [MapTo("T_Person")]

            作用于持久类或a property or a field

            作用于持久类时:指定持久类映射的表名称。如果没有指定,默认的表名就是类名。

            作用于property或field时:表的列名称。

            参数是表名或列名,是区分大小写的。

       

        [Persistent("CreatedOn")] 强制映射字段

            作用于a property or a field

XPO一般只对持久类中的可写property和public field进行持久化操作。因此对只读的field可以加上该特性进行强制持久化。

参数:表名(可选)

       

[NonPersistent]

            作用于a class, property or a field

                 指明不对类或property,field进行持久化操作。

            参数无。

       

[DbType]

            指定列创建时使用的数据类型。

            参数:字符串的数据类型表示。

   

[MapInheritance(MapInheritanceType.OwnTable)]

            作用于持久类。

            两个持久类是继承关系时,持久信息的存储方式。

            参数:

                MapInheritanceType.OwnTable :各自独立的表,分别存储独有部分。

                MapInheritanceType.ParentTable :都在父表存储。

       

        [Delayed("document")]

            只能作用于Property。

            延迟数据装载,当持久类构造时并不装载数据,只是property首次被访问时才装载。

            和类XPDelayedProperty结合使用才能实现延迟装载的功能。

            参数:引用的XPDelayedProperty 类型field 名称。

 

        [Size(SizeAttribute.Unlimited)] 数据长度

            作用范围a property or a field。

指定映射的表字段长度。只是当创建字段时才体现。当字段已经存在,XPO此时不会检查该值。

            参数:数值的长度或者SizeAttribute.Unlimited(不限制长度)

                  可以不指定。如果是string,默认是100。

           

        [Key ] ,[Key(true)],[Key(AutoGenerate = true)] 

作用于a property or a field。

指定主键。每个持久类都需要一个指定为key的propery or field。XPObject和XPBaseObject的一个明显差别就是XPObject已有一个OId主键

参数:bool型(可选)。是否由XPO自动生成键值(Int或GUID)。默认是false。

       

        [Indexed]

            作用于a property or a field。

                 指定索引。默认情况下改索引是非唯一索引。

            没有构造参数。但可以通过set来设置为唯一索引[Indexed(Unique=true)]

 

        [OptimisticLocking(false)] 

            作用于持久类。

        是否乐观锁定(感谢format 的指错)。如果锁定,修改后提交时,XPO会检查原始数据是否已经被改变,而不是who lastest who win。XPO在持久类映射的表类加一个系统字段“OptimisticLockField”,显然是用来标记状态的。因此如果是映射到视图时,要显式设置为不锁定。

            参数:bool值(可选,默认是true)

 

        [ValueConverter(typeof(实现转换接口(抽象类ValueConverter)的类))] 

            作用于property。

值和类型转换,挺有意思的一个功能。从数据库提取值和保存值都可以作一个转换工作。

       

        [NullValue("")]

            作用于简单数据类型的a property or field。

                 指定对应库中值为null时,持久类中对应的数据。反之也是。

            参数:根据不同的数据类型,引入不同的参数。看例子比较方便:

         public class Example : XPObject {
              [NullValue(Int32.MinValue)]
              public int NullOnMinValueFieldInt;
               
              [NullValue(0)]
              public int NullOnZeroFieldInt;
         [NullValue("")]
              public string NullOnEmptyStringFieldString;
         [NullValue("NULL")]
              public string NullOnNULLFieldString;
            }
    

          本想只列出常用的,但看看代码,就差两个就列完了。
      [ExplicitLoading]

[MemberDesignTimeVisibility]

 

Attribute

Description

AggregatedAttribute

Indicates that a property or field references other aggregated persistent objects.

AssociationAttribute

Specifies the association name for the property which represents a relationship between objects.

CustomAttribute

Specifies a custom attribute for a class or member.

DbTypeAttribute

Specifies the database type of the column that a property is mapped to.

DefaultMembersPersistence

Specifies which members are implied as persistent by default.

DeferredDeletionAttribute

Enables deferred object deletion.

DelayedAttribute

Indicates that the property's value should not be loaded when a persistent object is being loaded. The property will be loaded the first time it is accessed.

DisplayNameAttribute

Specifies the member's display name.

ExplicitLoadingAttribute

Specifies that the information used to retrieve persistent objects that are referenced by the current property, is included in a query used to load this property.

IndexedAttribute

Indicates that a property or field participates in index creation.

KeyAttribute

Indicates that a property or field is a key.

MapInheritanceAttribute

Specifies the type of object-relational inheritance mapping for the class.

MemberDesignTimeVisibilityAttribute

Specifies whether a property or class is visible at design time.

NoForeignKeyAttribute

Disables automatic creation of the FOREIGN KEY Constraints.

NonPersistentAttribute

Indicates that a class, property or field will not be stored in a persistent data store.

NullValueAttribute

Associates the constant with the null value of a property or field of the simple type.

OptimisticLockingAttribute

Specifies that a persistent object's state can be locked during a session.

PersistentAliasAttribute

Indicates that a property's value can be evaluated from the persistent fields or stored in a single persistent field.

PersistentAttribute

Indicates that a property, field or class will be stored in a persistent data store.

SizeAttribute

Specifies the maximum number of characters that can be stored in a column which is created to store the data of a property or field.

ValueConverterAttribute

Specifies that a persistent property has a converter for its value.

 

 

 

 

 

 

 

 

 

 

XPO注意事项

1、对二进制大对象字段的存取

    使用延迟装载(Delayed Loading)

       这里必须指定一个私有的XPDelayedProperty类型的属性,并且加上Attribute,设计上有点繁琐。

       public class Customer: XPObject {

        ...

        private XPDelayedProperty document = new XPDelayedProperty();

        [Delayed("document")]

        public Byte[] Attachment {

               get { return (Byte[])document.Value; }

               set { document.Value = value; }

        }

    }

 

2、事务的支持:

事务在数据库程序内是不可或缺的。

显然该功能是由Session提供的。

Account account = new Account();

        Session.DefaultSession.BeginTransaction();

        try {

               account.Amount = amount;

               account.Save();

               Session.DefaultSession.CommitTransaction();

        }

        catch (Exception e) {

               Session.DefaultSession.RollbackTransaction();

               account.Reload();

        }

 

注意在Exception发生时,使用了Reload()。

 

 

3、保存之前的数据有效性检查:

    class Account: XPObject {

            public double Amount = DefaultAmount;

            protected override void BeforeSave() {

                base.BeforeSave();

                if(!IsDeleted) {

                    if (Amount < 0) {

                        throw new Exception("Negative amount");

                    }

                }

            }

        }

    注意先判断了IsDeleted。

 

 

 

 

 

 

XPO 的数据表示

XPObject

 

XPCollection

 

XPView

 

Pageable Collection(XPCursor)

 

Session.GetObjects

 

XPO中查询数据:

对于查询,就是指定一定的条件获取一个数据集合。在XPO中,返回结果的集合用XPCollection作统一处理

 
XPCollection collection = new XPCollection(typeof(Person));
 
XPCollection xpCollectionPerson = new XPCollection(typeof(Person),
CriteriaOperator.Parse("IsMale==false"));

 

XPO中返回记录的分页处理:

在XPO中,除了XPCollection外,还有一个XPCursor提供了一个获取返回记录的另外一种方式。和XPCollection返回全部的满足条件的集合不同,XPCursor根据XPCursor.PageSize的设置依次返回满足条件的每页数据。
 
XPCursor这种特性在处理数据量比较大的表是十分有用的,可以减少每次内存的使用量和减少返回的时间。

当然,每次翻页则需要重新获取数据。

 

取得某个XPObject    Session.GetObjectByKey

gpspatrolforelec20080402.TSitus obj = (gpspatrolforelec20080402.TSitus)xposessoin.GetObjectByKey(typeof(gpspatrolforelec20080402.TSitus), 151);

 

 

 

 

 

 

 

 

Criteria Language Syntax

The criteria language, provided by eXpress Persistent Objects (XPO), is used in queries for persistent objects built using the CriteriaOperator.Parse method. It allows you to query for objects using standard object oriented syntax, and also includes several operators used to compare complex values.

Familiar Visual Basic and C# Syntax

The following examples show identical expressions. The first example is similar to Visual Basic .NET syntax. The second example is similar to C#. The criterion selects persistent objects whose Name property equals "John" or Age property equals 30:

Name = 'John' Or Age = 30

Name == 'John' || Age == 30

Literals

The following table lists the types supported by the XPO criteria language.

Type

Delimiter

Description

DateTime

#

Date and time comparison values.

Enumeration

 

Enumeration comparison values. To specify an enumeration value in criteria, use its name enclosed in apostrophes:

Status = 'InProgress'

If an enumeration value has an initializer, you can use the initializer value:

Status = 1

Note that you cannot specify an enumeration value via its qualified name. So, the following criteria is incorrect:

Status = Status.InProgress

Guid

{}

Guid comparison values. A Guid may only be used in a relational operation with equality or inequality operators.

Numeric

 

Numeric comparison values.

String

'

String comparison values.

Operators

The following tables list available operators.

Aggregation

Operators that perform aggregate operations on collections.

Name

Description

Usage

Avg

Evaluates an average of all values in a collection.

CriteriaOperator.Parse("Accounts.Avg(Amount) = 75")

Count

Returns the number of objects in a collection.

CriteriaOperator.Parse("Accounts.Count > 1")

Exists

Determines whether a collection property marked with the AssociationAttribute contains objects.

CriteriaOperator.Parse("Accounts.Exists")

Max

Returns the maximum expression value in a collection.

CriteriaOperator.Parse("Accounts.Max(Amount) > 75")

Min

Returns the minimum expression value in a collection.

CriteriaOperator.Parse("Accounts.Min(Amount) < 10")

Sum

Returns a sum of all expression values in a collection.

CriteriaOperator.Parse("Accounts.Sum(Amount) > 150")

Binary

Logical expressions that consist of comparison operations between two operands.

Name

Description

Usage

BitwiseAnd

Represents the bitwise AND operator.

CriteriaOperator.Parse("Roles & 1 = 1")

BitwiseOr

Represents the bitwise OR operator.

CriteriaOperator.Parse("Roles | 253 = 255")

BitwiseXor

Represents the bitwise XOR operator.

CriteriaOperator.Parse("Roles ^ 253 = 255")

Divide

Represents the division operator.

CriteriaOperator.Parse("Accounts.Max(Amount) / Accounts.Min(Amount) > 10")

Equal

Represents the Boolean equality operator.

CriteriaOperator.Parse("Name = 'John'")

Greater

Represents the Boolean greater-than operator.

CriteriaOperator.Parse("Age > 20")

GreaterOrEqual

Represents the Boolean greater-than-or-equal-to operator.

CriteriaOperator.Parse("Age >= 20")

Less

Represents the Boolean less-than operator.

CriteriaOperator.Parse("Age < 20")

LessOrEqual

Represents the Boolean less-than-or-equal-to operator.

CriteriaOperator.Parse("Age <= 20")

Like

Represents the LIKE operator that determines whether a specific character string matches a specified pattern.

The following wildcard characters are supported:

·  % matches a string of zero or more characters. For instance:

CriteriaOperator.Parse("Name like 'Jo%'") - returns all the objects whose Name begins with 'Jo'.

CriteriaOperator.Parse("Name like '%car%'") - returns all the objects whose Name contains the 'car' substring.

·  _ matches a single character. For instance:

CriteriaOperator.Parse("Name like 'car_'") - returns all the objects whose Name consists of four characters, and begins with 'car'.

·  [ ] identifies a single character within the specified range ([a-c]) or set ([abc]). For instance:

CriteriaOperator.Parse("Name like '[A-C]%'") - returns all the objects whose Name begins with 'A', 'B' or 'C'.

·  [^] excludes a single character not within the specified range ([^a-c]) or set ([^abc]). For instance:

CriteriaOperator.Parse("Name like 're[^de]%'") - returns all the objects whose Name begins with 're', and where the following letter is not 'd' or 'e'.

CriteriaOperator.Parse("Name like 'Jo%' or Name like '%ob'")

Minus

Represents the subtraction operator.

CriteriaOperator.Parse("Age - 30 > 0")

Modulo

Represents the modulus operator (computes the remainder after dividing its first operand by its second).

CriteriaOperator.Parse("Age % 50 = 0")

Multiply

Represents the multiplication operator.

CriteriaOperator.Parse("Accounts.Sum(Amount) * 20 >= 3000")

NotEqual

Represents the Boolean inequality operator.

CriteriaOperator.Parse("Name != 'John'")

Plus

Represents the addition operator.

CriteriaOperator.Parse("Age + 50 = 100")

Function Operators

The table below lists only basic logical and string management operators. For a complete set of available function operators, refer to the FunctionOperatorType enumeration description.

Name

Description

Usage

Concat

Concatenates one or more strings.

CriteriaOperator.Parse("Name like concat ('%J', 'o%')")

Custom

This operator allows you to implement a custom function that is supported by a specific database engine.

To learn more, see the How to: Implement a Custom Criteria Language Operator topic.

CriteriaOperator.Parse("Custom('CustomFunctionName', [Property], 'Value', ...)")

Where CustomFunctionName is a mandatory parameter followed by the custom function's parameters.

Iif

Returns one of two values depending upon the value of a logical expression.

The function requires three operands of the CriteriaOperator class:

1 - determines the logical expression;

2 - specifies the value that will be returned if the logical expression evaluates to true;

3 - specifies the value that will be returned if the logical expression evaluates to false.

CriteriaOperator.Parse("(Iif (Accounts.Sum(Amount) > 150, 1, 0) = 1)")

IsNull

Compares the first operand with the null value. This function requires one or two operands of the CriteriaOperator class.

The value returned depends upon the number of arguments.

If a single argument is passed, the function returns true if the operand is null, otherwise, false is returned.

If two operands are passed, the function returns the second operand if the first operand is null, otherwise, the first operand is returned.

CriteriaOperator.Parse("isnull(Name)")

Len

Returns the length of the string specified by an operand.

The operand should be an object of the CriteriaOperator type.

CriteriaOperator.Parse("Len(Name) > 3")

Lower

Converts all characters in a string operand to lowercase.

The operand should be an object of the CriteriaOperator type.

CriteriaOperator.Parse("Lower(Name) like '%jo%'")

Substring

Returns a substring extracted from the specified string. This function requires two or three operands of the CriteriaOperator class.

If two operands are passed the substring will be extracted from the beginning of the original string. The operands should be defined as follows:

1 - an original string;

2 - an integer that specifies the length of the substring.

If three operands are passed, a substring can be subtracted starting from any position in the original string. The operands should be defined as follows:

1 - an original string;

2 - an integer that specifies the zero-based index at which the substring to return begins;

3 - an integer that specifies the length of the substring.

CriteriaOperator.Parse("Substring(Name, 0, 2) = 'Bo'")

Trim

Returns a string containing a copy of a specified string with no leading or trailing spaces.

This function requires a single operand of the CriteriaOperator class that refers to the original string.

CriteriaOperator.Parse("Trim(Name) = 'Bob'")

Upper

Converts all characters in a string operand to uppercase.

The operand should be an object of the CriteriaOperator type.

CriteriaOperator.Parse("Upper(Name) like '%JO%'")

Group

Logical expressions which group two or more operands with a logical AND or OR.

Name

Description

Usage

And

Groups operands with logical AND.

CriteriaOperator.Parse("Name = 'John' and Age = 30")

Or

Groups operands with logical OR.

CriteriaOperator.Parse("Name = 'John' or Age = 30")

Unary

Unary operators which perform operations on a single expression.

Name

Description

Usage

BitwiseNot

Represents the bitwise NOT operator.

CriteriaOperator.Parse("~Roles = 251")

IsNull

Represents the operator which determines whether or not a given expression is NULL.

CriteriaOperator.Parse("Name is null")

Minus

Represents the unary negation (-) operator.

CriteriaOperator.Parse("-Age = -20")

Not

Represents the logical NOT.

CriteriaOperator.Parse("not (Name = 'John' or Age = 30)")

Plus

Represents the unary plus (+) operator.

CriteriaOperator.Parse("Age = +10")

Miscellaneous

Name

Description

Usage

Between

Determines whether the expression lies between the specified range of values.

CriteriaOperator.Parse("Age between (20, 40)")

In

Determines whether a value matches any value in the specified list.

CriteriaOperator.Parse("Name in ('John', 'Bob', 'Nick')")

Related Property Reference

To refer to a related property, use brackets "[ ]". For instance, the following query returns all persistent objects that have an Account with an Amount of 100:

Accounts[Amount == 100]

Grouping Clauses with Brackets

When a query traverses an object relationship, the XPO architecture ensures that a related object exists before comparing property values. Because of this behavior, it is important to use brackets to ensure that your query returns the intended results.

For instance, the following query for objects of Customer type returns all of the customers where an Account exists with a Date of 8/25/2006 and where an account exists with an Amount of 100:

Accounts[Date == #8/25/2006#] && Accounts[Amount == 100]

To search for all customers that have an Account with both a Date of 8/25/2006 and an Amount of 100, construct the query as in the following example:

Accounts[Date == #8/25/2006# && Amount == 100]

Parent Relationship Traversal Operator

The '^' character is used to refer to the parent in a parent-child relationship. The parent relationship traversal operator allows you to access parent objects in expressions written in the context of a child. The parent operator can be applied successively to navigate multiple parent relationships. Consider the following expression:

C#

Copy Code

XPCollection<Customer> Customers = new XPCollection<Customer>();

Customers.Criteria = CriteriaOperator.Parse("Orders[^.RegistrationDate == Date]");

Visual Basic

Copy Code

Dim Customers As XPCollection(Of Customer) = New XPCollection(Of Customer)()

Customers.Criteria = CriteriaOperator.Parse("Orders[^.RegistrationDate == Date]")

Here, the "RegistrationDate" property refers to the Customer objects and the "Date" property refers to the Order objects. This expression selects all the customers who have made at least one order on the day they registered. The parent relationship traversal operator can only be used within brackets in the context of the ContainsOperator. So, the following expression is incorrect:

C#

Copy Code

XPCollection<Order> Orders = new XPCollection<Order>();

Orders.Criteria = CriteriaOperator.Parse("^.RegistrationDate == Date");

Visual Basic

Copy Code

Dim Orders As XPCollection(Of Order) = New XPCollection(Of Order)()

Orders.Criteria = CriteriaOperator.Parse("^.RegistrationDate == Date")

Operator Precedence

When an expression contains multiple operators, operator precedence controls the order in which the elements of the expression are evaluated.

·                         Literal values

·                         Parameters

·                         Identifiers

·                         OR (left-associative)

·                         AND (left-associative)

·                         '.' relationship qualifier (left-associative)

·                         ==, !=, Like

·                         <, >, <=, >=

·                         -, + (left-associative)

·                         *, /, % (left-associative)

·                         NOT

·                         unary -

·                         In

·                         Iif

·                         Trim(), Len(), Substring(), IsNull()

·                         '[]' (for set-restriction)

·                         '()'

The default precedence can be changed by grouping elements with parentheses. For instance, in the first of the following two code samples, the operators will be performed in the default order. In the second code sample, the addition operation will be performed first, because its associated elements are grouped with parentheses, and the multiplication operation will be performed last:

Accounts[Amount == 2 + 48 * 2]

Accounts[Amount == (2 + 48) * 2]

Case Sensitivity

Operators are case insensitive. The case sensitivity of values depends on the data source.

Note

The behavior of certain operators is affected by the data source. For instance, by default, SQL Server Express 2005 is configured as case insensitive. In this case, the following expression always evaluates to true, and all persistent objects are selected:

Lower(Name) == Upper(Name)

Upcasting

The upcasting feature allows you to access properties of a class different from a collection's base class. This feature is useful if you have a collection typed for a base class, and in reality it holds objects of a derived class. Since this collection is typed for the base class, you are only able to directly access its properties. To access the properties of the derived class, they must be upcasted.

The following code snippet demonstrates this. The ExtendedProperty is upcasted in the second line to specify that it is a property of the CustomClass derived from the CustomBaseClass:

C#

Copy Code

XPCollection<CustomBaseClass> myCollection = new XPCollection<CustomBaseClass>(session);

CriteriaOperator filterOperator = CriteriaOperator.Parse("<CustomClass>ExtendedProperty > 0");

myCollection.Filter = filterOperator;

Visual Basic

Copy Code

Dim myCollection As XPCollection(Of CustomBaseClass) = New XPCollection(Of CustomBaseClass)(session)

Dim filterOperator As CriteriaOperator = CriteriaOperator.Parse("<CustomClass>ExtendedProperty > 0")

myCollection.Filter = filterOperator

Escaping Keywords

If the property name of an object is also a keyword, then you can escape the property name by prefixing it with an @ sign. For instance, in the @Or = 'value' query, the CriteriaOperator.Parse method interprets @Or as the property named "Or", not the logical operator OR

定义

CriteriaOperator criteria = new BinaryOperator(

    new OperandProperty("City"), new OperandValue("Chicago"),

    BinaryOperatorType.NotEqual

);

CriteriaOperator criteria = CriteriaOperator.Parse("City != 'Chicago'");

 

// Retrieves a collection of the Contact objects which match the criteria that represents

// the logical expression (DefaultAddress.City <> "Chicago").

XPCollection collection = new XPCollection(typeof(Contact),

    CriteriaOperator.Parse("DefaultAddress.City != 'Chicago'")

);

 

 

 

 

 

 

 

 

 

XPO 使用记录

1. 一般实体类直接继承自 XPObject,如果需要自定义主键或自增字段则可继承自XPCustomObject。

 

2. 继承自XPBaseObject的实体类,Delete后将被直接物理删除。而XPCustomObject & XPObject的继承类则是软删除。

  (1) 实体对象软删除

  customer.Delete();

  customer.Save();

 

  (2) 物理删除

  Session.DefaultSession.PurgeObject(customer);

 

  (3) 物理删除所有被标记软删除的记录。

  Session.DefaultSession.PurgeDeletedObjects();

 

  (4) 清除数据库中所有数据。

  Session.DefaultSession.ClearDatabase();

 

  (5) 恢复被软删除的记录。

  while(true)

  {

    o = (MyObject)Session.DefaultSession.FindObject(typeof(MyObject), new NotOperator(new NullOperator("GCRecord")), true);

    if (o == null)

    {

      break;

    }

    o.GCRecord = null;

    o.Save();

  } 

 

  (6) 批量删除

 

  XPCollection customers = new XPCollection(typeof(Product), new BinaryOperator("Customer", "Tom"));

  Session.DefaultSession.Delete(customers);

  Session.DefaultSession.Save(customers);

 

7)直接通过传SQL语句获得对象集合的方法!


  Dim command As IDbCommand
        Dim reader As IDataReader
        command = DevExpress.Xpo.Session.DefaultSession.ConnectionProvider.CreateCommand()
        command.CommandText = "Select * from VS_Service where F0302=2" 
        reader = command.ExecuteReader()

        DataGrid1.DataSource = reader
        DataGrid1.DataBind()
        reader.Close()

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

使用XPO连接高于5.2.5.0版本的MySQL

 

XPO自然是支持MySQL的,只需要在项目里添加对MySql.Data的DLL(从MySQL官网下载Connector/Net可得)和DevExpress.Xpo.v9.2.Providers的DLL引用,并且在项目的入口点构造XpoDataLayer时指定使用MySQL即可。

  然而测试时遇到问题。手里的9.2.10版本的XPO,在编译时使用的是5.2.5.0版本的MySQL,而下载到的最新的是6.2.2.0,不能用。

  这时我们可以修改并重新编译XPO的源代码,但我想没人高兴这么做。

  还有个简单的办法,即在Config文件中添加如下代码:

<?xml version="1.0"?> 
<configuration> 
    <runtime> 
        <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> 
            <dependentAssembly> 
                <assemblyIdentity name="MySql.Data" publicKeyToken="c5687fc88969c44d" culture="neutral"/> 
                <bindingRedirect oldVersion="5.2.5.0" newVersion="6.2.2.0"/> 
            </dependentAssembly> 
        </assemblyBinding> 
    </runtime> 
</configuration>

知秋君
上一篇 2024-08-16 14:48
下一篇 2024-08-16 14:12

相关推荐