本篇文章,介绍Microsoft Dynamics CRM 2011的组织服务中的RetrieveMultiple方法。
RetreiveMultiple方法,用于获取实体的多个实例,该方法的签名如下:
1 public virtual EntityCollection RetrieveMultiple (
2 QueryBase query
3 )
RetreiveMultiple方法的输入参数是QueryBase类的对象。QueryBase是一个基类,有多个子类,其类树如下图所示:
由上图可见,QueryBase有三个派生类,分别是QueryByAttribute、QueryExpression以及FetchExpression。下面依次进行介绍。
QueryByAttribute类。使用QueryByAttribute类生成根据一组值测试一组属性的查询。该类的主要属性列表如下所示:
属性 |
说明 |
EntityName |
指定检索哪种类型的实体。一个查询表达式仅检索一个实体类型集合。 |
ColumnSet |
指定要检索的属性(列)的集合。 |
Attributes |
指定查询中选择的属性集合。 |
Values |
指定查询执行时要查找的属性值。 |
Orders |
指定从查询返回记录的顺序。 |
PageInfo |
指定从查询返回的页数和每页的记录数。 |
借由QueryByAttribute,形成的等价SQL语句如下:
1 Select
2 [ColumnSet]
3 From
4 [EntityName]
5 Where
6 Attibutes[1] = Values[1] And
7 Attibutes[2] = Values[2] And
8 .......
9 Attibutes[N] = Values[N]
其中,所有处于方括号(“[”与“]”)之中的内容,均是来自于QueryByAttribute的各个属性值。样例代码如下:
1 //创建QueryByAttribute实例,指定待检索实体的逻辑名称account
2 QueryByAttribute queryByAttribute = new QueryByAttribute("account");
3
4 //指定返回结果包含的数据列集合
5 queryByAttribute.ColumnSet = new ColumnSet("name", "address1_city", "emailaddress1");
6
7
8 //指定检索条件,address1_city = ‘Detroit’
9
10 //首先指定检索条件的列字段信息
11 queryByAttribute.Attributes.AddRange("address1_city");
12 //接着指定检索条件中的列值信息
13 queryByAttribute.Values.AddRange("Detroit");
14
15 //指定检索条件,accountnumber = ‘abc’
16
17 //首先指定检索条件的列字段信息
18 queryByAttribute.Attributes.AddRange("accountnumber");
19 //接着指定检索条件中的列值信息
20 queryByAttribute.Values.AddRange("abc");
21
22
23 //调用组织服务的RetrieveMultiple方法,将queryByAttribute对象传递给RetrieveMultiple方法
24 EntityCollection retrieved = _serviceProxy.RetrieveMultiple(queryByAttribute);
25 //遍历返回结果
26 foreach (var c in retrieved.Entities)
27 {
28 System.Console.WriteLine("Name: " + c.Attributes["name"]);
29 System.Console.WriteLine("Address: " + c.Attributes["address1_city"]);
30 System.Console.WriteLine("E-mail: " + c.Attributes["emailaddress1"]);
31 }
FetchExpression,最主要的属性就是Query属性,可以将FetchXml字符串赋值给Query属性。FetchXml是MS CRM的专有查询语言,FetchXml包括能够计算总和、平均值、最小值、最大值和计数的分组和聚合函数:sum/avg/min/max/count(*)/count(属性名称)。FetchXml的书写非常之繁复,可以通过第三方提供的工具,或者通过“高级查找”界面中的“下载FetchXml”获得。首先,利用CRM提供的图形化界面创建需要的查找,而后点击Ribbon工具条中的“下载FetchXml”按钮,如下图所示:
对应于上面查找条件的FetchXml语句如下图所示:
将这个FetchXml字符串赋值给FetchExpression的Query属性,而后调用RetrieveMultiple方法,将FetchExpression对象作为参数传递给该方面即可。下面是样例代码:
1 string query = “<fetch version='1.0' output-format='xml-platform' mapping='logical' distinct='false'><entity name='account'><attribute name='address1_telephone1' /><attribute name='customersizecode' /><attribute name='accountratingcode' /><attribute name='accountnumber' /><attribute name='name' /><attribute name='accountid' /><order attribute='accountnumber' descending='false' /><order attribute='name' descending='false' /><filter type='and'><condition attribute='primarycontactid' operator='not-null' /><condition attribute='statecode' operator='eq' value='0' /></filter><link-entity name='contact' from='contactid' to='primarycontactid' visible='false' link-type='outer' alias='a_410707b195544cd984376608b1802904'><attribute name='gendercode' /><attribute name='telephone1' /><attribute name='fullname' /></link-entity></entity></fetch>”;
2
3 FetchExpression fetchExpression = new FetchExpression(query);
4
5 EntityCollection retrieved = _serviceProxy.RetrieveMultiple(fetchExpression);
QueryExpression。使用QueryExpression类,可以生成复杂查询,可以使用 ConditionExpression、ColumnSet 和 FilterExpression 类为QueryExpression设置查询参数。QueryExpression 类可用于创建复杂查询。QueryByAttribute 类旨在作为简单的搜索方式,用于搜索属性匹配指定值的实体。
QueryExpression类的主要属性如下表所示:
属性 |
说明 |
EntityName |
指定将检索哪种类型的实体。一个查询表达式仅检索一个实体类型集合。 |
ColumnSet |
指定要检索的属性(列)的集合。 |
Criteria |
指定复杂条件和逻辑筛选器表达式,用于筛选查询结果。 |
Distinct |
指定查询的结果是否包含重复记录。 |
LinkEntities |
指定多个实体类型之间的链接。 |
Orders |
指定从查询返回的记录的顺序。 |
PageInfo |
指定从查询返回的页数和每页中的记录数量。 |
非常重要的一个属性是Criteria,该属性是FilterExpression类型。可以使用FilterExpression类生成表示多个条件的查询。例如,可以创建等效于 SQL 语句(如([FirstName] = 'Joe' OR [FirstName] = 'John') AND [City] = 'Redmond'
)的查询表达式。FilterExpression的属性列表如下所示:
属性 |
说明 |
Conditions |
获取或设置包括属性、条件运算符和属性值的条件表达式。 |
FilterOperator |
获取或设置逻辑 AND/OR 筛选器运算符。它使用 LogicalOperator 枚举进行设置。 |
Filters |
获取或设置用于筛选查询结果的条件和逻辑筛选器表达式的层次结构。 |
FilterExpression 类还包含一些帮助程序方法,通过它们可以更轻松地创建查询。AddCondition 方法可将 ConditionExpression 添加到 FilterExpression 的 Conditions 属性中,以减少构造条件表达式所需的代码量。AddFilter 方法可将新筛选器添加到 FilterExpression 类的 Filters 属性中。
除了Criteria之外,还需要注意的是LinkEntities属性,该属性用以指定多个实体之间的链接,从而形成 Account Join Contact On Account.PrimaryContactId = Contact.ContactId Join SystemUser On Account.OwnerId = SystemUser.SystemUserId样式的SQL语句。不过呢,该属性是只读的,需要使用
AddLink ( string linkToEntityName, string linkFromAttributeName, string linkToAttributeName )
或者
AddLink (string linkToEntityName, string linkFromAttributeName, string linkToAttributeName, JoinOperator joinOperator)方法创建实体之间的链接。
使用QueryExpression的样例代码如下所示,:
1 //创建样例数据
2
3 //创建联系人记录
4
5 Entity contact = new Entity("contact");
6 contact.Attributes["firstname"] = "ContactFirstName";
7 contact.Attributes["lastname"] = "ContactLastName";
8 Guid contactId = _orgService.Create(contact, null);
9
10 //创建三个客户记录,指定客户名称分别为“Test Account1”、“Test Account2”、“Test Account3”,并指定三个客户记录的主要联系人属性值为之前创建的联系人记录
11
12 Entity account = new Entity("account");
13 account["name"] = "Test Account1";
14 EntityReference primaryContactId = new EntityReference("contact", contactId);
15 account["primarycontactid"] = primaryContactId;
16
17 Guid accountId1 = _orgService.Create(account, null);
18 account["name"] = "Test Account2";
19 Guid accountId2 = _orgService.Create(account, null);
20 account["name"] = "Test Account3";
21 Guid accountId3 = _orgService.Create(account, null);
22
23 //创建QueryExpression实例,
24 QueryExpression qe = new QueryExpression();
25
26 //指定查询表达式要查询的实体为account
27 qe.EntityName = "account";
28
29 //指定返回值的列信息
30 qe.ColumnSet = new ColumnSet();
31 qe.ColumnSet.Columns.Add("name");
32
33 //指定链接的实体的信息
34
35 qe.LinkEntities.Add(new LinkEntity("account", "contact", "primarycontactid", "contactid", JoinOperator.Inner));
36 qe.LinkEntities[0].Columns.AddColumns("firstname", "lastname");
37 qe.LinkEntities[0].EntityAlias = "primarycontact";
38
39 //调用RetrieveMultiple方法
40
41 EntityCollection ec = _orgService.RetrieveMultiple(qe);
42
43 Console.WriteLine("Retrieved {0} entities", ec.Entities.Count);
44
45 //遍历返回结果
46 foreach (Entity act in ec.Entities)
47 {
48 Console.WriteLine("account name:" + act["name"]);
49 Console.WriteLine("primary contact first name:" + act["primarycontact.firstname"]);
50 Console.WriteLine("primary contact last name:" + act["primarycontact.lastname"]);
51 }