基于图1的XPO关系,列举常用的CriteriaOperator。
图1 示例XPO类
1.BetweenOperator 范围操作符如:100<=x<=200
年龄在20到30岁之间
Criteria.Parse("[Age] Between(20, 30)") //后略,直接给出字符串
new BetweenOperator("Age", 20, 30);
Id在Age2和Age之间的客户
new BetweenOperator("Id",
new OperandProperty("Age2"),new OperandProperty("Age"));
[Id] Between([Age2], [Age])
注意,Age2必须小于Age才能筛选出之间的集合
2.BinaryOperator 二元操作符,如:x>200
姓名以"J"开头new BinaryOperator(new OperandProperty("Age"),new OperandValue("J%"),BinaryOperatorType.Like);
[Age] Like 'J%'
Age等于Age2
new BinaryOperator(new OperandProperty("Age"), new OperandProperty("Age2"), BinaryOperatorType.Like)
[Age] Like [Age2]
3.ContainsOperator 集合操作符,集合中元素是否符合某种条件
订单数量大于50的客户
new ContainsOperator("Orders",new BinaryOperator("Amount",50,BinaryOperatorType.Greater));
[Orders][[Amount] > 50]
订单中某种产品的号码Number等于100的客户
new ContainsOperator(
"Orders", new ContainsOperator("Products",
new BinaryOperator(new OperandProperty("Number"),
new OperandValue(100), BinaryOperatorType.Equal)
));
[Orders][[Products][[Number] = 100]]
4.GroupOperator 组合操作符,利用它可以反复嵌套组成复杂的过滤表达式
姓名以T开头且年龄为10岁的客户
new GroupOperator(GroupOperatorType.And,
new BinaryOperator("Age",10),new BinaryOperator("Name","T%",BinaryOperatorType.Like));
[Age] = 10 And [Name] Like 'T%'
5.InOperator 允许属性值在某个范围内取值
年龄是1岁或96岁的客户
int [] ageList=new int[]{1,96};
CriteriaOperator filter = new InOperator("Age",ageList);
[Age] In (1, 96)
6.NotOperator 取反操作符
年龄不等于96岁的客户
new NotOperator(new BinaryOperator("Age", 96));
Not [Age] = 96
7.NullOperator 空值操作符
姓名为空的客户
new NullOperator("Name");
[Name] Is Null
8.Iif 类似于if.......else if...................else.........,可创建复杂的选择
姓名为Jack且Age大于3的客户,若没有则寻找姓名叫Mike且Age2大于3的客户,若还没有则寻找Id大于3的客户
CriteriaOperator.Parse(
"Iif(Name Like 'Jack', Age,Name Like 'Mike',Age2, Id) > 3")
9. "^." 父对象引用操作符
在父子关系中,即1对多关系中,1为父,多为子,在且仅在子对象集合的上下文中(即使用ContainsOperator过滤器时)可以使用"^."引用父对象,我们这里示例的Customer即为父,Orders为子
若要筛选某类客户customer,他们的Age2等于其订单Orders的数量Amount,则筛选表达式为:
CriteriaOperator filter = new ContainsOperator("Orders",
new BinaryOperator(new OperandProperty("Amount"), new OperandProperty("^.Age2"),BinaryOperatorType.Equal));
var list = ObjectSpace.GetObjects<Customer>(filter);
[Orders][[Amount] = [^.Age2]]
10. join连接
语法:[<JoinTypeName>][[^.ParentObjectProperty] = [JoinedObjectProperty]]
查询某类客户,他们的订单中,满足数量Amount等于客户Age2的订单数大于1笔
CriteriaOperator joinCriteria = new OperandProperty("^.Age2") == new OperandProperty("Amount");
JoinOperand joinOperand =
new JoinOperand("Orders", joinCriteria, Aggregate.Count, new OperandProperty("Order_Name"));
BinaryOperator criteria =
new BinaryOperator(joinOperand, new OperandValue(1), BinaryOperatorType.Greater);
var list = ObjectSpace.GetObjects<Customer>(criteria);
[<Orders>][[^.Age2] = [Amount]].Count([Order_Name]) > 1
再举一个:查询Id最大的Customer
CriteriaOperator criteria =
new BinaryOperator("Id", new JoinOperand("Customer", null, Aggregate.Max, new OperandProperty("Id")));
var list = ObjectSpace.GetObjects<Customer>(criteria);
[Id] = [<Customer>][].Max([Id])
可以这样理解JoinOperand的构造规则
JoinOperand(string joinTypeName, CriteriaOperator condition, Aggregate type, CriteriaOperator aggregatedExpression)
joinTypeName:连接类型名,即类名,注意在父子关系中是子类类名,不是父亲类中的子对象集合属性名!
condition:连接条件
type:聚合函数类型
aggregatedExpression:连接作用的属性
如第一个例子中:连接到的类是Orders,连接条件是Customer.Age2等于Orders.Amout,作用规则是求Orders.Order_Name(这里写成Orders别的任意属性都行)的数量
第二个例子中:连接到的类是Customer自己,无连接条件,作用规则是求Customer.Id的最大值