若要控制从相关表记录返回的数据,请使用包含导航属性的 $expand查询选项 。
- 查询中最多可以包含 15
$expand个选项。 每个$expand选项都会创建一个可能影响性能的联接。 - 展开集合值导航属性的查询可能会返回那些不反映最近更改的属性的缓存数据。 建议在
If-None-Match头中使用null的值来覆盖浏览器缓存。 了解如何使用 HTTP 标头 以获取更多信息。
| 选项 | Description | 详细信息 |
|---|---|---|
$select |
选择返回的属性。 | 选择列 |
$filter |
对于集合值导航属性,请限制返回的记录。 | 筛选行 |
$orderby |
对于集合值导航属性,控制返回的记录的顺序。 不支持嵌套 $expand。 |
嵌套的集合值导航属性$expand |
$top |
对于集合值导航属性,请限制返回的记录数。 不支持嵌套$expand。 |
集合类型导航属性中的嵌套$expand |
$expand |
展开相关实体集中的导航属性。 在 $expand 中使用 $expand 形成称为嵌套 $expand 的结构。 |
单值导航属性的嵌套扩展 和 集合值导航属性的嵌套扩展操作 |
这些选项是 OData 版本 4.0 第 1 部分:协议加 Errata 02 11.2.4.2.1 展开选项中所述的查询选项的子集。 Dataverse Web API 不支持选项 $skip、$count、$search 和 $levels。
将这些选项与 $expand 一起使用,并添加在导航属性名称后的括号中。 用分号分隔每个选项(;)。
例如,以下查询:
请求
account.name属性联接
AccountTasks集合值导航属性请求:-
task.subject属性 -
task.subject其中包含字符串“Task” - 按
task.createdon日期排序,降序
-
/accounts?$select=name&$expand=Account_Tasks($select=subject;$filter=contains(subject,'Task');$orderby=createdon desc)
利用 $select 对列进行限制
与任何查询一样,使用$select时,请始终限制返回的$expand列。 例如,以下请求在扩展结果中从contact.fullname实体类型返回contact.fullname和task.subject值:
请求:
GET [Organization URI]/api/data/v9.2/accounts?$select=name
&$expand=primarycontactid($select=fullname),Account_Tasks($select=subject)
Prefer: odata.maxpagesize=1
If-None-Match: null
Accept: application/json
OData-MaxVersion: 4.0
OData-Version: 4.0
响应:
HTTP/1.1 200 OK
OData-Version: 4.0
Preference-Applied: odata.maxpagesize=1
{
"@odata.context": "[Organization URI]/api/data/v9.2/$metadata#accounts(name,primarycontactid(fullname),Account_Tasks(subject))",
"value": [
{
"@odata.etag": "W/\"80649578\"",
"name": "Litware, Inc. (sample)",
"accountid": "78914942-34cb-ed11-b596-0022481d68cd",
"primarycontactid": {
"fullname": "Susanna Stubberod (sample)",
"contactid": "70bf4d48-34cb-ed11-b596-0022481d68cd"
},
"Account_Tasks": [
{
"@odata.etag": "W/\"80649460\"",
"subject": "Task 1 for Litware",
"_regardingobjectid_value": "78914942-34cb-ed11-b596-0022481d68cd",
"activityid": "f68393c1-34cb-ed11-b597-000d3a993550"
}
],
"Account_Tasks@odata.nextLink": "[Organization URI]/api/data/v9.2/accounts(78914942-34cb-ed11-b596-0022481d68cd)/Account_Tasks?$select=subject"
}
],
"@odata.nextLink": "[Organization URI]/api/data/v9.2/accounts?$select=name&$expand=primarycontactid($select=fullname),Account_Tasks($select=subject)&$skiptoken=%3Ccookie%20pagenumber=%222%22%20pagingcookie=%22%253ccookie%2520page%253d%25221%2522%253e%253caccountid%2520last%253d%2522%257b78914942-34CB-ED11-B596-0022481D68CD%257d%2522%2520first%253d%2522%257b78914942-34CB-ED11-B596-0022481D68CD%257d%2522%2520%252f%253e%253c%252fcookie%253e%22%20istracking=%22False%22%20/%3E"
}
导航属性类型差异
扩展集合值导航属性可以使响应的大小以难以预测的方式很大。 必须包含限制来控制返回的数据量。 可以使用分页来限制记录数。 详细了解分页结果
对应用于集合值导航属性的嵌套$expand选项的分页方式有显著差异。 详细了解如何扩展集合值导航属性
展开单值导航属性
以下示例演示如何检索联系人记录,包括主要联系人和创建记录的用户。
请求:
GET [Organization URI]/api/data/v9.2/accounts?$select=name
&$expand=primarycontactid($select=contactid,fullname),createdby($select=fullname)
Prefer: odata.maxpagesize=2
If-None-Match: null
Accept: application/json
OData-MaxVersion: 4.0
OData-Version: 4.0
响应:
HTTP/1.1 200 OK
Content-Type: application/json; odata.metadata=minimal
Preference-Applied: odata.maxpagesize=2
OData-Version: 4.0
{
"@odata.context": "[Organization URI]/api/data/v9.2/$metadata#accounts(name,primarycontactid(contactid,fullname),createdby(fullname))",
"value": [
{
"@odata.etag": "W/\"80649578\"",
"name": "Litware, Inc. (sample)",
"accountid": "78914942-34cb-ed11-b596-0022481d68cd",
"primarycontactid": {
"contactid": "70bf4d48-34cb-ed11-b596-0022481d68cd",
"fullname": "Susanna Stubberod (sample)"
},
"createdby": {
"fullname": "System Administrator",
"systemuserid": "4026be43-6b69-e111-8f65-78e7d1620f5e",
"ownerid": "4026be43-6b69-e111-8f65-78e7d1620f5e"
}
},
{
"@odata.etag": "W/\"80649580\"",
"name": "Adventure Works (sample)",
"accountid": "7a914942-34cb-ed11-b596-0022481d68cd",
"primarycontactid": {
"contactid": "72bf4d48-34cb-ed11-b596-0022481d68cd",
"fullname": "Nancy Anderson (sample)"
},
"createdby": {
"fullname": "System Administrator",
"systemuserid": "4026be43-6b69-e111-8f65-78e7d1620f5e",
"ownerid": "4026be43-6b69-e111-8f65-78e7d1620f5e"
}
}
],
"@odata.nextLink": "[Organization URI]/api/data/v9.2/accounts?$select=name%0A&$expand=primarycontactid($select=contactid,fullname),createdby($select=fullname)&$skiptoken=%3Ccookie%20pagenumber=%222%22%20pagingcookie=%22%253ccookie%2520page%253d%25221%2522%253e%253caccountid%2520last%253d%2522%257b7A914942-34CB-ED11-B596-0022481D68CD%257d%2522%2520first%253d%2522%257b78914942-34CB-ED11-B596-0022481D68CD%257d%2522%2520%252f%253e%253c%252fcookie%253e%22%20istracking=%22False%22%20/%3E"
}
createdby单值导航属性返回 systemuser EntityType 的实例。
systemuserid 属性和 ownerid 属性都会返回。 这是因为systemuser继承自主体 EntityType,并通过此继承与ownerid 共享主键。
但是, User (SystemUser) 表 具有 SystemUserId 的主键。 这两个属性systemuserid和ownerid具有相同的值。
详细了解 EntityType 继承
返回引用
可以通过使用 /$ref 选项扩展单值导航属性,返回相关记录的引用或链接,而不是直接返回数据。 以下示例返回具有每个主要联系人 URL 的属性的 JSON 对象 @odata.id 。
请求:
GET [Organization URI]/api/data/v9.2/accounts?$select=name
&$expand=primarycontactid/$ref
Accept: application/json
OData-MaxVersion: 4.0
OData-Version: 4.0
响应:
HTTP/1.1 200 OK
Content-Type: application/json; odata.metadata=minimal
Preference-Applied: odata.maxpagesize=2
OData-Version: 4.0
{
"@odata.context": "[Organization URI]/api/data/v9.2/$metadata#accounts(name,primarycontactid,primarycontactid/$ref())",
"value": [
{
"@odata.etag": "W/\"80649578\"",
"name": "Litware, Inc. (sample)",
"_primarycontactid_value": "70bf4d48-34cb-ed11-b596-0022481d68cd",
"accountid": "78914942-34cb-ed11-b596-0022481d68cd",
"primarycontactid": {
"@odata.id": "[Organization URI]/api/data/v9.2/contacts(70bf4d48-34cb-ed11-b596-0022481d68cd)"
}
},
{
"@odata.etag": "W/\"80649580\"",
"name": "Adventure Works (sample)",
"_primarycontactid_value": "72bf4d48-34cb-ed11-b596-0022481d68cd",
"accountid": "7a914942-34cb-ed11-b596-0022481d68cd",
"primarycontactid": {
"@odata.id": "[Organization URI]/api/data/v9.2/contacts(72bf4d48-34cb-ed11-b596-0022481d68cd)"
}
}
],
"@odata.nextLink": "[Organization URI]/api/data/v9.2/accounts?$select=name%0A&$expand=primarycontactid/$ref&$skiptoken=%3Ccookie%20pagenumber=%222%22%20pagingcookie=%22%253ccookie%2520page%253d%25221%2522%253e%253caccountid%2520last%253d%2522%257b7A914942-34CB-ED11-B596-0022481D68CD%257d%2522%2520first%253d%2522%257b78914942-34CB-ED11-B596-0022481D68CD%257d%2522%2520%252f%253e%253c%252fcookie%253e%22%20istracking=%22False%22%20/%3E"
}
只能将 /$ref 选项用于单值导航属性。 如果将它与集合值导航属性一起使用,则会出现以下错误:
{
"error": {
"code": "0x80060888",
"message": "Expand with $ref is only supported on lookup type navigation property."
}
}
单值导航属性的嵌套扩展
通过将选项嵌套在另一$expand$expand个选项中,可以将单值导航属性扩展到多个级别。
以下查询返回 task 记录,并展开与其相关的 contact、与 contact 相关的 account,以及创建 account 记录的 systemuser:
请求:
GET [Organization URI]/api/data/v9.2/tasks?$select=subject
&$expand=regardingobjectid_contact_task($select=fullname;
$expand=parentcustomerid_account($select=name;
$expand=createdby($select=fullname)))
Accept: application/json
OData-MaxVersion: 4.0
OData-Version: 4.0
Prefer: odata.maxpagesize=2
响应:
HTTP/1.1 200 OK
Content-Type: application/json; odata.metadata=minimal
Preference-Applied: odata.maxpagesize=2
OData-Version: 4.0
{
"@odata.context": "[Organization URI]/api/data/v9.2/$metadata#tasks(subject,regardingobjectid_contact_task(fullname,parentcustomerid_account(name,createdby(fullname))))",
"value": [
{
"@odata.etag": "W/\"80730855\"",
"subject": "Task 1 for Susanna Stubberod",
"activityid": "e9a8c72c-dbcc-ed11-b597-000d3a993550",
"regardingobjectid_contact_task": {
"fullname": "Susanna Stubberod (sample)",
"contactid": "70bf4d48-34cb-ed11-b596-0022481d68cd",
"parentcustomerid_account": {
"name": "Litware, Inc. (sample)",
"accountid": "78914942-34cb-ed11-b596-0022481d68cd",
"createdby": {
"fullname": "System Administrator",
"systemuserid": "4026be43-6b69-e111-8f65-78e7d1620f5e",
"ownerid": "4026be43-6b69-e111-8f65-78e7d1620f5e"
}
}
}
},
{
"@odata.etag": "W/\"80730861\"",
"subject": "Task 2 for Susanna Stubberod",
"activityid": "c206f534-dbcc-ed11-b597-000d3a993550",
"regardingobjectid_contact_task": {
"fullname": "Susanna Stubberod (sample)",
"contactid": "70bf4d48-34cb-ed11-b596-0022481d68cd",
"parentcustomerid_account": {
"name": "Litware, Inc. (sample)",
"accountid": "78914942-34cb-ed11-b596-0022481d68cd",
"createdby": {
"fullname": "System Administrator",
"systemuserid": "4026be43-6b69-e111-8f65-78e7d1620f5e",
"ownerid": "4026be43-6b69-e111-8f65-78e7d1620f5e"
}
}
}
}
],
"@odata.nextLink": "[Organization URI]/api/data/v9.2/tasks?$select=subject&$expand=regardingobjectid_contact_task($select=fullname;$expand=parentcustomerid_account($select=name;$expand=createdby($select=fullname)))&$skiptoken=%3Ccookie%20pagenumber=%222%22%20pagingcookie=%22%253ccookie%2520page%253d%25221%2522%253e%253cactivityid%2520last%253d%2522%257bC206F534-DBCC-ED11-B597-000D3A993550%257d%2522%2520first%253d%2522%257bE9A8C72C-DBCC-ED11-B597-000D3A993550%257d%2522%2520%252f%253e%253c%252fcookie%253e%22%20istracking=%22False%22%20/%3E"
}
展开集合值导航属性
响应中存在一些重要差异,具体取决于是否在查询中的任何位置使用嵌套 $expand 的集合值导航属性。
| 嵌套$expand | 单个$expand | |
|---|---|---|
| 分页 | 对展开的行进行分页。 | 仅对 EntitySet 资源进行分页。
<property name>@odata.nextLink 扩展行的 URL 不包括分页信息。 |
$top 或 $orderby 受支持 |
否 | 是的 |
| 支持 N:N 关系 | 否。 请参阅 包含 N:N 关系的嵌套$expand | 是的 |
集合值导航属性中使用的单个 $expand
如果仅使用单级 $expand,则不会对展开的行应用分页。 如果包含 Prefer: odata.maxpagesize 请求标头,则分页仅应用于查询的 EntitySet 资源。
每个扩展的集合值导航属性返回一个 <property>@odata.nextLink 不包含分页信息的 URL。 这是一个 URL,表示附加了查询选项的关系的筛选集合。 可以使用该 URL 发送单独的 GET 请求,并返回原始请求中返回的相同行。 可以将分页应用于该请求。
由于没有对已扩展的记录应用分页,因此每个扩展后的集合值导航属性最多可以返回 5,000 条相关表记录。 根据你的数据和查询,可能涉及大量数据。 返回大量数据可能会影响性能,并可能导致请求超时。请谨慎对待你撰写的查询。 可以使用$top和$filter$orderby选项来控制返回的记录总数。
以下示例在检索帐户记录时包含单次扩展Account_Tasks和contact_customer_accounts。 请求 Prefer: odata.maxpagesize=1 标头可确保在第一页中只返回一个帐户记录。
请求:
GET [Organization URI]/api/data/v9.2/accounts?$select=name,accountid
&$expand=Account_Tasks($select=subject),contact_customer_accounts($select=fullname)
Prefer: odata.maxpagesize=1
Accept: application/json
OData-MaxVersion: 4.0
OData-Version: 4.0
响应:
HTTP/1.1 200 OK
Content-Type: application/json; odata.metadata=minimal
Preference-Applied: odata.maxpagesize=1
OData-Version: 4.0
{
"@odata.context": "[Organization URI]/api/data/v9.2/$metadata#accounts(name,accountid,Account_Tasks(subject),contact_customer_accounts(fullname))",
"value": [
{
"@odata.etag": "W/\"80649578\"",
"name": "Litware, Inc. (sample)",
"accountid": "78914942-34cb-ed11-b596-0022481d68cd",
"Account_Tasks": [
{
"@odata.etag": "W/\"80730894\"",
"subject": "Task 1 for Litware",
"_regardingobjectid_value": "78914942-34cb-ed11-b596-0022481d68cd",
"activityid": "be9f6557-e2cc-ed11-b597-000d3a993550"
},
{
"@odata.etag": "W/\"80730903\"",
"subject": "Task 2 for Litware",
"_regardingobjectid_value": "78914942-34cb-ed11-b596-0022481d68cd",
"activityid": "605dbd65-e2cc-ed11-b597-000d3a993550"
},
{
"@odata.etag": "W/\"80730909\"",
"subject": "Task 3 for Litware",
"_regardingobjectid_value": "78914942-34cb-ed11-b596-0022481d68cd",
"activityid": "a718856c-e2cc-ed11-b597-000d3a993550"
}
],
"Account_Tasks@odata.nextLink": "[Organization URI]/api/data/v9.2/accounts(78914942-34cb-ed11-b596-0022481d68cd)/Account_Tasks?$select=subject",
"contact_customer_accounts": [
{
"@odata.etag": "W/\"80648695\"",
"fullname": "Susanna Stubberod (sample)",
"_parentcustomerid_value": "78914942-34cb-ed11-b596-0022481d68cd",
"contactid": "70bf4d48-34cb-ed11-b596-0022481d68cd"
}
],
"contact_customer_accounts@odata.nextLink": "[Organization URI]/api/data/v9.2/accounts(78914942-34cb-ed11-b596-0022481d68cd)/contact_customer_accounts?$select=fullname"
}
],
"@odata.nextLink": "[Organization URI]/api/data/v9.2/accounts?$select=name,accountid&$expand=Account_Tasks($select=subject),contact_customer_accounts($select=fullname)&$skiptoken=%3Ccookie%20pagenumber=%222%22%20pagingcookie=%22%253ccookie%2520page%253d%25221%2522%253e%253caccountid%2520last%253d%2522%257b7A914942-34CB-ED11-B596-0022481D68CD%257d%2522%2520first%253d%2522%257b78914942-34CB-ED11-B596-0022481D68CD%257d%2522%2520%252f%253e%253c%252fcookie%253e%22%20istracking=%22False%22%20/%3E"
}
将此响应与以下包含嵌套 $expand 的示例进行比较。 请水平滚动示例响应,以查看只有 @odata.nextLink 帐户结果的 URL 包含分页信息。
集合值导航属性中的嵌套$expand
如果在查询的任何位置使用嵌套的$expand,并且包含Prefer: odata.maxpagesize请求标头,则分页将应用于每个已展开的集合。
每个扩展的集合值导航属性返回一个包含分页信息的 <property>@odata.nextLink URL。 可以使用该 URL 发送单独的 GET 请求,它将返回原始请求中未包含的下一组记录。
不能使用 $top 或 $orderby 选项来限制使用嵌套 $expand返回的记录总数。 如果使用以下选项,将返回以下错误:
{
"error": {
"code": "0x80060888",
"message": "Only $select and $filter clause can be provided while doing $expand on many-to-one relationship or nested one-to-many relationship."
}
}
以下示例基于上一个示例并使用相同的数据。 唯一的区别是,在单值导航属性的 URL 中添加这个嵌套$expand,用于返回联系人的拥有用户:;$expand=owninguser($select=fullname)。
请求:
GET [Organization URI]/api/data/v9.2/accounts?$select=name,accountid
&$expand=Account_Tasks($select=subject),contact_customer_accounts($select=fullname;
$expand=owninguser($select=fullname))
Prefer: odata.maxpagesize=1
Accept: application/json
OData-MaxVersion: 4.0
OData-Version: 4.0
响应:
HTTP/1.1 200 OK
Content-Type: application/json; odata.metadata=minimal
Preference-Applied: odata.maxpagesize=1
OData-Version: 4.0
{
"@odata.context": "[Organization URI]/api/data/v9.2/$metadata#accounts(name,accountid,Account_Tasks(subject),contact_customer_accounts(fullname,owninguser(fullname)))",
"value": [
{
"@odata.etag": "W/\"80649578\"",
"name": "Litware, Inc. (sample)",
"accountid": "78914942-34cb-ed11-b596-0022481d68cd",
"Account_Tasks": [
{
"subject": "Task 1 for Litware",
"activityid": "be9f6557-e2cc-ed11-b597-000d3a993550"
}
],
"Account_Tasks@odata.nextLink": "[Organization URI]/api/data/v9.2/accounts(78914942-34cb-ed11-b596-0022481d68cd)/Account_Tasks?$select=subject,description&$skiptoken=%3Ccookie%20pagenumber=%222%22%20pagingcookie=%22%253ccookie%2520page%253d%25221%2522%2520countOfRecords%253d%25221%2522%253e%253cactivityid%2520last%253d%2522%257bbe9f6557-e2cc-ed11-b597-000d3a993550%257d%2522%2520first%253d%2522%257bbe9f6557-e2cc-ed11-b597-000d3a993550%257d%2522%2520%252f%253e%253c%252fcookie%253e%22%20istracking=%22False%22%20/%3E",
"contact_customer_accounts": [
{
"fullname": "Susanna Stubberod (sample)",
"contactid": "70bf4d48-34cb-ed11-b596-0022481d68cd",
"owninguser": {
"fullname": "System Administrator",
"systemuserid": "4026be43-6b69-e111-8f65-78e7d1620f5e",
"ownerid": "4026be43-6b69-e111-8f65-78e7d1620f5e"
}
}
],
"contact_customer_accounts@odata.nextLink": "[Organization URI]/api/data/v9.2/accounts(78914942-34cb-ed11-b596-0022481d68cd)/contact_customer_accounts?$select=fullname&$expand=owninguser($select=fullname)&$skiptoken=%3Ccookie%20pagenumber=%222%22%20pagingcookie=%22%253ccookie%2520page%253d%25221%2522%2520countOfRecords%253d%25221%2522%253e%253ccontactid%2520last%253d%2522%257b70bf4d48-34cb-ed11-b596-0022481d68cd%257d%2522%2520first%253d%2522%257b70bf4d48-34cb-ed11-b596-0022481d68cd%257d%2522%2520%252f%253e%253c%252fcookie%253e%22%20istracking=%22False%22%20/%3E"
}
],
"@odata.nextLink": "[Organization URI]/api/data/v9.2/accounts?$select=name,accountid&$expand=Account_Tasks($select=subject,description),contact_customer_accounts($select=fullname;$expand=owninguser($select=fullname))&$skiptoken=%3Ccookie%20pagenumber=%222%22%20pagingcookie=%22%253ccookie%2520page%253d%25221%2522%2520countOfRecords%253d%25221%2522%253e%253caccountid%2520last%253d%2522%257b78914942-34cb-ed11-b596-0022481d68cd%257d%2522%2520first%253d%2522%257b78914942-34cb-ed11-b596-0022481d68cd%257d%2522%2520%252f%253e%253c%252fcookie%253e%22%20istracking=%22False%22%20/%3E"
}
将此响应与前面的示例进行比较,该示例不使用嵌套 $expand。 在此响应中:
- 请求
Prefer: odata.maxpagesize=1标头应用于返回的taskAccount_Tasks记录。 - 只返回一个任务,而不是返回三个任务。
- URL
Account_Tasks@odata.nextLink返回接下来的两个任务。 - 请水平滚动示例响应,以查看
Account_Tasks@odata.nextLink、contact_customer_accounts@odata.nextLink和@odata.nextLinkURL 中包含的分页信息。
嵌套 $expand 与 N:N 关系
当集合值导航属性表示 N:N 关系时,使用嵌套 $expand 语句时会收到以下错误:
{
"error": {
"code": "0x80060888",
"message": "The navigation property '<NAME>' cannot be expanded. Only many-to-one relationships are supported for nested expansion."
}
}
例如,使用 Dynamics Lead 表(与 联系人表 有 contactleads_association N:N 关系),以下查询返回错误,因为它包含;$expand=createdby。
GET [Organization URI]/contacts?$select=fullname$expand=contactleads_association($select=fullname;$expand=createdby)
若要避免此错误,可以使用 FetchXml 构造查询。 例如:
<fetch>
<entity name='contact'>
<attribute name='fullname' />
<link-entity name='contactleads'
from='contactid'
to='contactid'
alias='cl'>
<link-entity name='lead'
from='leadid'
to='leadid'
alias='lead'>
<attribute name='fullname' />
<link-entity name='systemuser'
from='systemuserid'
to='createdby'
alias='systemuser'>
<attribute name='fullname' />
</link-entity>
</link-entity>
</link-entity>
</entity>
</fetch>
后续步骤
了解如何对行进行排序。