前文回顾

前面的文章一步一步教你使用AgileEAS.NET基础类库进行应用开发-基础篇-演示ORM的基本操作一文给大家介绍了如果使用ORM实现数据的读取、插入、更新与删除基本业务也讲解了ORM开发基本流程。

问题提出

在前面的一文中我展示了数据表的查询示例,关键的一句代码:table.Query()返回字典表的所有数据,演示的例子就这么用了,但是在实际的使用过程中你不可能每次都取把全表数据取回来,业务的处理需要查询指定条件的数据这是必要的,把表中的数据全部取回来怎么办,再说了,如果记录上百万、千万,估计DbServer和网络也就崩溃了。

如果解决

在AgileEAS.NET平台的ORM组件中提供了条件查询的功能,用于实现where和order的功能,我们来看看ITable接口中的查询定义:
    /// <summary>/// 条件查询,从数据库读取Table 对象所对应数据库实体数据。/// </summary>/// <param name="condition">数据查询条件,为空引用则返回整个数据库实体。</param>void Query(Condition condition); 
在Query方法中提供了带Condition类型参数的重载,Condition对象用于构造一个查询条件(where … order by …),目前不支持having子句。
在应用开发中条件参数的主要工作是构造条件(Condition),条件由基于的条件元素Element组成和排序元素OrderElement组成,即Element是组成Condition的基本单位,Condition与Element、Element与Element、Condition与Condition都可以组合成新的的Condition对象,以下是其他结构图:
p_w_picpath
Condition提供了这种树状的组合方式,由Condition对象的AddElement和AddCondition两个重载方法完成这种机制:
{1KRG5JN0)K{UKH4[[B`%WM
Condition与Condition、Condition与Element、Element与Element的组成提供了And与Or两种组合方式,由枚举ElementCombineType进行定义:
    /// <summary>/// Condition 类的数据元素(Element)之间的组合方法。/// </summary>public enum ElementCombineType{/// <summary>/// And,两个Element 对象之间是以And 为组合条件。/// </summary>And = 0x0000,/// <summary>/// Or,两个Element 对象之间是以Or 为组合条件。/// </summary>Or = 0x0001		}
系统提供了EqualTo(等于)、GreaterThan(大于)、SqlCondition(SQL语句条件)等一共19种条件元素,除SqlCondition条件之外其他的都有其固定的含义,SqlCondition条件用于其他条件无法完成或者说用其他条件实现难度较大的情况下使用,条件元素的类型由枚举ElementType定义:
AW_@CKBV(PZTI}]R}GBN$UP
各条件的详细功能请参考AgileEAS.NET平台基础类库手册。

案例介绍

关于条件查询以及条件的构造的知识差不多也就是这些,讲起来也没有什么讲头,重点才于如何组合这些条件实现复杂的业务,在今天的案例中我选择性的演示几个条件的用法,所使用的数据还是商品字典,达到以下的功能:
1.查询单位为“1*瓶/瓶”的所有商品,并且按商品编码排序,演示EqualTo条件与排序条件。
2.查询商品编码前1位为“1”的所有商品,并且按商品编码倒序排序。演示SQL条件的使用。
3.查询商品编码前2位为“1a”的所有商品,不处理排序。演示Like条件的使用。
4.查询记录ID从100到500的记录,不处理排序。演示BetWeen条件的使用。
5.查询记录ID从100到500并且编码前1位为“1”的所有商品记录,不处理排序。演示两个条件元素And组合的使用。
6.查询记录ID从100到5000并且编码前1位为“1”的所有商品记录以及商品编码前2位为“1a”并且单位为“1*瓶/瓶”的商品记录,不处理排序。演示两个条件Or组合的使用。
为了实现上述要求,并且保持非DAL层的代码不涉及具体的数据库结果,我们需要在生成的DAL代码中增加上述查询的实现:
1 ///<summary>
2 ///根据单位取得产品字典记录。
3 ///</summary>
4 ///<param name="unit">单位。</param>
5 publicvoidGetProductListByUnit(stringunit)
6 {
7 Condition condition =this.CreateCondition();
8 condition.AddElement("UNIT", unit);
9 //condition.AddElement("UNIT", unit, ElementType.EqualTo); //等同
10 //condition.AddElement("UNIT", unit, ElementType.EqualTo, ElementCombineType.And); //等同
11 condition.AddOrderElement("IDN");
12 this.Query(condition);
13 }
14 
15 ///<summary>
16 ///查询编码前一位为X的商品记录。
17 ///</summary>
18 ///<param name="code">单位。</param>
19 publicvoidGetProductListByCode1(stringcode)
20 {
21 Condition condition =this.CreateCondition();
22 condition.AddElement("SQL", "left(CODE,1)='"+code +"'", ElementType.SqlCondition);
23 //condition.AddElement("SQL", "left(CODE)='" + code + "'", ElementType.SqlCondition, ElementCombineType.And); //等同
24 condition.AddOrderElement("IDN", true);
25 this.Query(condition);
26 }
27 
28 ///<summary>
29 ///查询编码前2位为XX的商品记录。
30 ///</summary>
31 ///<param name="code">单位。</param>
32 publicvoidGetProductListByCode2(stringcode)
33 {
34 Condition condition =this.CreateCondition();
35 condition.AddElement("CODE", code, ElementType.MatchPrefix);
36 //condition.AddElement("CODE", code, ElementType.MatchPrefix, ElementCombineType.And); //等同
37 this.Query(condition);
38 }
39 
40 ///<summary>
41 ///查询IDN从X到Y的记录。
42 ///</summary>
43 ///<param name="iStart">X</param>
44 ///<param name="iEnd">Y</param>
45 publicvoidGetProductListByIDN(intiStart, intiEnd)
46 {
47 Condition condition =this.CreateCondition();
48 
49 List<int>values =newList<int>(2);
50 values.Add(iStart);
51 values.Add(iEnd);
52 
53 condition.AddElement("IDN", values, ElementType.BetWeen);
54 this.Query(condition);
55 }
56 
57 ///<summary>
58 ///查询记录ID从X到Y并且编码前1位为“X”的所有商品记录。
59 ///</summary>
60 ///<param name="iStart">X</param>
61 ///<param name="iEnd">Y</param>
62 publicvoidGetProductListByIDNAndCode(intiStart, intiEnd, stringcode)
63 {
64 Condition condition =this.CreateCondition();
65 List<int>values =newList<int>(2);
66 values.Add(iStart);
67 values.Add(iEnd);
68 condition.AddElement("IDN", values, ElementType.BetWeen);
69 condition.AddElement("SQL", "left(CODE,1)='"+code +"'", ElementType.SqlCondition);
70 
71 this.Query(condition);
72 }
73 
74 ///<summary>
75 ///查询记录ID从X到Y并且编码前12位为“Xx”的所有商品记录。
76 ///</summary>
77 ///<param name="iStart">X</param>
78 ///<param name="iEnd">Y</param>
79 publicvoidGetProductListByIDNOrCodeUnit(intiStart, intiEnd, stringcode, stringunit)
80 {
81 Condition condition =this.CreateCondition();
82 List<int>values =newList<int>(2);
83 values.Add(iStart);
84 values.Add(iEnd);
85 condition.AddElement("IDN", values, ElementType.BetWeen);
86 
87 Condition condition2 =this.CreateCondition();
88 condition2.AddElement("CODE", code, ElementType.MatchPrefix);
89 condition2.AddElement("UNIT", unit);
90 
91 condition.AddCondition(condition2, ElementCombineType.Or);
92 
93 this.Query(condition);
94 }
我们在控制台演示项目中使用这些查询
1 class ConditionDemo
2 {
3 private void OutPut(ProductList table)
4 {
5 foreach (Product product in table.Rows)
6 {
7 System.Console.WriteLine(string.Format("Idn={0}\tCode={1}\tName={2}\tSpec={3}\tUnit={4}\tDescription={5}", product.Idn, product.Code, product.Name, product.Spec, product.Unit, product.Description));
8 }
9 }
10 
11 /// <summary>
12 /// 查询单位为“1*瓶/瓶”的所有商品,并且按商品编码排序,演示EqualTo条件与排序条件。
13 /// </summary>
14 public void DemoCondition1()
15 {
16 ProductList table = new ProductList();
17 table.OrmAccessor = OrmContext.OrmAccessor;
18 table.GetProductListByUnit("1*瓶/瓶");
19 this.OutPut(table);
20 }
21 
22 /// <summary>
23 /// 查询商品编码前1位为“1”的所有商品,并且按商品编码倒序排序。演示SQL条件的使用。
24 /// </summary>
25 public void DemoCondition2()
26 {
27 ProductList table = new ProductList();
28 table.OrmAccessor = OrmContext.OrmAccessor;
29 table.GetProductListByCode1("1");
30 this.OutPut(table);
31 }
32 
33 /// <summary>
34 /// 查询商品编码前2位为“1a”的所有商品,不处理排序。演示Like条件的使用。
35 /// </summary>
36 public void DemoCondition3()
37 {
38 ProductList table = new ProductList();
39 table.OrmAccessor = OrmContext.OrmAccessor;
40 table.GetProductListByCode2("1a");
41 this.OutPut(table);
42 }
43 
44 /// <summary>
45 /// 查询记录ID从100到500的记录,不处理排序。演示BetWeen条件的使用。
46 /// </summary>
47 public void DemoCondition4()
48 {
49 ProductList table = new ProductList();
50 table.OrmAccessor = OrmContext.OrmAccessor;
51 table.GetProductListByIDN(100, 500);
52 this.OutPut(table);
53 }
54 
55 /// <summary>
56 /// 查询记录ID从100到500并且编码前1位为“1”的所有商品记录,不处理排序。演示两个条件元素And组合的使用。
57 /// </summary>
58 public void DemoCondition5()
59 {
60 ProductList table = new ProductList();
61 table.OrmAccessor = OrmContext.OrmAccessor;
62 table.GetProductListByIDNAndCode(100, 500, "1");
63 this.OutPut(table);
64 }
65 
66 /// <summary>
67 /// 查询记录ID从100到500并且编码前1位为“1”的所有商品记录以及商品编码前2位为“1a”并且单位为“1*瓶/瓶”的商品记录,不处理排序。演示两个条件Or组合的使用。
68 /// </summary>
69 public void DemoCondition6()
70 {
71 ProductList table = new ProductList();
72 table.OrmAccessor = OrmContext.OrmAccessor;
73 table.GetProductListByIDNOrCodeUnit(100, 500, "1a", "1*瓶/瓶");
74 this.OutPut(table);
75 }
76 }
案例输出结果:
p_w_picpath
有关本例子所涉及的数据表结构请参考基于AgileEAS.NET平台基础类库进行应用开发-总体说明及数据定义一文,有关数据对象模型定义文件、文档、DDL脚本请下载:http://files.cnblogs.com/eastjade/demo.db.doc.sql.rar,本文代码下载:ORM.Demo2.rar。
链接
一步一步教你使用AgileEAS.NET基础类库进行应用开发-系列目录
AgileEAS.NET平台开发指南-系列目录
AgileEAS.NET应用开发平台介绍-文章索引
AgileEAS.NET平台应用开发教程-案例计划
AgileEAS.NET官方网站
敏捷软件工程实验室
QQ群:116773358