XPO 学习笔记(二)
XPO的条件相关类。
XPO的条件对象用来生成数据筛选条件,实际就是SQL语句条件语法树(条件表达式的组合)的对象表示方法。
一、主要相关类:
1、继承于抽象类CriteriaOperator的类系列。
继承于CriteriaOperator的子类有:
BetweenOperator
取范围的条件表达式类,如:1000 <= Total Price <= 2000
BinaryOperator
二元表达式类,最基本的表达式,比如:TotalPrice>100
ContainsOperator
包含表达式类,比如:exists
GroupOperator
组合表达式类,利用它进行反复嵌套组合,可以组成任意复杂的条件树。
InOperator
在某个值列表范围内的表达式,可以认为是SQL中的in
NotOperator
取反表达式,对应SQL中的not
NullOperator
取空值表达式,对应SQL中的 IsNull
2、辅助CriteriaOperator的CriteriaOperand类系列。
继承于抽象类CriteriaOperand的子类有:
AggregateOperand
聚合操作,可以在此时使用各种聚合函数(以枚举方式提供),类似于groupby 再加Having
OperandProperty
表达式中的引用类成员(实体类(XPPersistent)的可持久化的属性(property)或字段(field))。对应的就是表字段。
OperandValue
表达式中的值
OperandValueBase
OperandValue的基类。
二、详细描述:
(A)、条件对象系列:
CriteriaOperator
条件运算类是所有条件对象的抽象基类。没有任何具体方法,只是在类上加了属性Serializable。(看来Dev是想让大家手动以序列化方式持久)。
BetweenOperator
范围运算类:用来表示某个值范围的条件表达式。
构造函数:
public BetweenOperator(CriteriaOperand objectProperty, CriteriaOperand leftOperand, CriteriaOperand rightOperand)
public BetweenOperator(string property, CriteriaOperand leftOperand, CriteriaOperand rightOperand) : this(new OperandProperty(property), leftOperand, rightOperand)
比如:1000 <= Total Price <= 2000 写成new BetweenOperator("TotalPrice", 1000, 2000))
BinaryOperator
二元运算对象,也就是一个二元运算表达式。
构造函数:
public BinaryOperator(CriteriaOperand opLeft, CriteriaOperand opRight, BinaryOperatorType type)
public BinaryOperator(string propertyName, object value, BinaryOperatorType type) :
this(new OperandProperty(propertyName), new OperandValue(value), type)
参数type的类型BinaryOperatorType是二元操作符枚举,看名称就知道意思啦。
BinaryOperatorType{ Equal, Greater , GreaterOrEqual , Less , LessOrEqual , Like, NotEqual }
比如:TotalPrice>100 写成: new BinaryOperator("TotalPrice", 10, BinaryOperatorType.Greater)
ContainsOperator
包含表达式:
这个原始文档是:Used in a search criteria to filter collection contents.
大家知道两个实体类之间是一对多或多对多时,其中一个对另一个类的引用是通过XPCollection类型实现的。对此类型的属性或字段的筛选就必须使用ContainsOperator
构造函数:
public ContainsOperator(OperandProperty objectProperty, CriteriaOperator operand)
public ContainsOperator(string property, CriteriaOperator operand) : this(new OperandProperty(property), operand)
比如两个类:
public class Customer : XPObject
{
/// <summary>
/// 有多个订单,是聚集关系。
/// </summary>
[Association("CustomerOrders", typeof (Order)), Aggregated]
public XPCollection Orders
{
get { return GetCollection("Orders"); }
}
}
/// <summary>
/// 订单
/// </summary>
public class Order : XPObject
{
/// <summary>
/// 订单的所属用户
/// </summary>
[Association("CustomerOrders")]
public Customer Customer;
/// <summary>
/// 订单金额
/// </summary>
public Decimal Freight;
}
这连个类是一对多关系,我想查询订单金额等于1000的用户。
XPCollection collection = new XPCollection(typeof(Customer),
new ContainsOperator("Orders ",new BinaryOperator("Freight ",1000,BinaryOperatorType.Equal));
实际是两个条件对象的组合使用。
GroupOperator
组合表达式类,非常强大,利用它进行反复嵌套组合,可以组成任意复杂的条件树。
可以组合CriteriaOperator类系列的任何类,包括自身。
构造函数:
public GroupOperator(CriteriaOperator[] operands);
Operands are grouped by the GroupOperatorType.And type.
public GroupOperator(GroupOperatorType type, CriteriaOperator[] operands);
比如:有这么四个类,用户、角色、地址、订单
它们之间的关系除用户和订单是一对多之外,其他都是多对多的关系。
/// <summary>
/// 用户
/// </summary>
public class Customer : XPObject
{
public string Name = "";
public string CompanyName = "";
public string Phone = "";
public string Fax = "";
[ValueConverter(typeof(CodeConvertor))]
public string Sex="2";
/// <summary>
/// 有多个订单,是聚集关系。
/// </summary>
[Association("CustomerOrders", typeof (Order)), Aggregated]
public XPCollection Orders
{
get { return GetCollection("Orders"); }
}
/// <summary>
/// 一个用户可以有多个地址
/// </summary>
[Association("CustomerAddresses", typeof (Address))]
public XPCollection Addresses
{
get { return GetCollection("Addresses"); }
}
/// <summary>
/// 角色,一个用户可以在多个角色中。
/// </summary>
[Association("CustomersGroups", typeof (Group))]
public XPCollection Groups
{
get { return GetCollection("Groups"); }
}
public Customer()
{
}
public Customer(string newName, string newCompanyName, string newPhone, string newFax)
{
Name = newName;
CompanyName = newCompanyName;
Phone = newPhone;
Fax = newFax;
}
}
/// <summary>
/// 地址
/// </summary>
public class Address : XPObject
{
public string Street = "";
/// <summary>
/// 一个地址可能有多个用户。
/// </summary>
[Association("CustomerAddresses")]
public Customer Customer;
public Address()
{
}
public Address(string theStreet)
{
Street = theStreet;
}
}
/// <summary>
/// 订单
/// </summary>
public class Order : XPObject
{
public DateTime OrderDate;
public DateTime RequiredDate;
public DateTime ShippedDate;
public int ShipVia;
/// <summary>
/// 订单金额
/// </summary>
public Decimal Freight;
/// <summary>
/// 订单的所属用户
/// </summary>
[Association("CustomerOrders")]
public Customer Customer;
public Order()
{
}
public Order(DateTime newOrderDate, DateTime newRequiredDate, DateTime newShippedDate, int newShipVia, Decimal newFreight)
{
OrderDate = newOrderDate;
RequiredDate = newRequiredDate;
ShippedDate = newShippedDate;
ShipVia = newShipVia;
Freight = newFreight;
}
}
/// <summary>
/// 角色
/// </summary>
public class Group : XPObject
{
public string Name = "";
/// <summary>
///一个角色拥有的用户
/// </summary>
[Association("CustomersGroups", typeof (Customer))]
public XPCollection Customers
{
get { return GetCollection("Customers"); }
}
public Group()
{
}
public Group(string newName)
{
Name = newName;
}
}
查找(角色是Administrator并且订单金额大于20) 或者 家庭地址在天津的用户的条件对象:
new GroupOperator
(
GroupOperatorType.Or,
new ContainsOperator("Addresses",new BinaryOperator("Street","天津",BinaryOperatorType.Equal)),
new GroupOperator
(
GroupOperatorType.And,
new ContainsOperator("Groups",new BinaryOperator("Name","Administrator",BinaryOperatorType.Equal)),
new ContainsOperator("Orders",new BinaryOperator("Freight",20,BinaryOperatorType.GreaterOrEqual))
)
)
InOperator
组成类似sql 表达式中in的表达式:
构造函数:
public InOperator(CriteriaOperand leftOperand, CriteriaOperand[] operands);
public InOperator(string propertyName, ICollection values);
很简单,不用举例
NotOperator
类似sql中的not操作。
构造函数:
public NotOperator(CriteriaOperator operand);
比如:new NullOperator("Company")
NullOperator
取空值。
构造函数
public NullOperator(string propertyName);
public NullOperator(OperandProperty operand);
比如:new NotOperator(new NullOperator("Company"))
(B)、条件对象的操作符系列:
CriteriaOperand
条件对象的操作符,包含运算数,运算符,运算对象等等,是个抽象类。
AggregateOperand
聚合操作,可以在此时使用各种聚合函数(以枚举方式提供),类似于groupby 再加Having 。
构造函数 :
public AggregateOperand(OperandProperty objectProperty, OperandProperty aggregateProperty, Aggregate type, CriteriaOperator criteria);
还是那些类,想查找订单金额总数小于100的人
new XPCollection(typeof(Customor), new BinaryOperator(new AggregateOperand(new OperandProperty("Orders"), new OperandProperty("Freight "),Aggregate.Sum, null), new OperandValue(100), BinaryOperatorType.Less))
可以看到使用了聚合函数类型枚举
public enum Aggregate{ Avg , Count , Max ,Min , None }
或者地址有类似于上海,并且该地址是唯一的:
new XPCollection(typeof(Cutomor), new BinaryOperator(new AggregateOperand("Addresses",
new BinaryOperator("Street", "上海%", BinaryOperatorType.Like)), new OperandValue(1), BinaryOperatorType.Equal))
OperandProperty
表达式中的引用类成员(实体类(XPPersistent)的可持久化的属性(property)或字段(field))。对应的就是表字段。
构造函数:
public OperandProperty(string propertyName);
例子上面都有了,要注意非持久化的类成员是不可以直接使用的。
OperandValue
表达式中的值。
构造函数:
public OperandValue(object value);
没有什么好说的。
OperandValueBase
OperandValue的基类。基本没用。