使用 FetchXML 关联表

如 使用 FetchXml 的查询数据中所述,使用 实体元素选择表来启动查询。

使用 链接实体元素 描述要通过查询返回的相关表中的数据。 使用以下属性:

属性 简短说明 :在链接实体元素参考中查找更多详细信息
name 关联表的逻辑名称。
from 来自相关表中列的逻辑名称,与 to 属性中指定的列匹配。
to 父元素 to 中与 from 属性中指定的关联表列匹配的列的逻辑名称。
link-type 要使用的链接类型。 默认值是 inner,它将结果限制为两个表中具有匹配值的行。
其他有效值为:
- outer
- any
- not any
- all
- not all
- exists
- in
- matchfirstrowusingcrossapply
了解链接类型选项。
alias 表示结果中相关表的名称。
intersect 指示 link-entity 用于联接表且不返回任何列。

基本示例

以下查询根据帐户记录中的 PrimaryContactId 查找列从帐户表和联系人表中返回最多五条记录:

<fetch top='5'>
   <entity name='account'>
      <attribute name='name' />
      <link-entity name='contact'
         from='contactid'
         to='primarycontactid'
         link-type='inner'
         alias='contact'>
         <attribute name='fullname' />
      </link-entity>
   </entity>
</fetch>

结果如下所示:

 -----------------------------------------------------------------
 | name                             | contact.fullname           |
 -----------------------------------------------------------------
 | Litware, Inc. (sample)           | Susanna Stubberod (sample) |
 -----------------------------------------------------------------
 | Adventure Works (sample)         | Nancy Anderson (sample)    |
 -----------------------------------------------------------------
 | Fabrikam, Inc. (sample)          | Maria Campbell (sample)    |
 -----------------------------------------------------------------
 | Blue Yonder Airlines (sample)    | Sidney Higa (sample)       |
 -----------------------------------------------------------------
 | City Power & Light (sample)      | Scott Konersmann (sample)  |
 -----------------------------------------------------------------

局限性

最多可以向查询添加 15 link-entity 个元素。 每个link-entity都会向查询添加JOIN,并增加查询的执行时间。 此限制可保护性能。 如果将 15 link-entity 个以上的元素添加到查询,则会收到以下错误消息:

代码:0x8004430D
编号: -2147204339
消息:Number of link entities in query exceeded maximum limit.

子元素

在元素中 link-entity ,可以像在父元素上一样添加子元素,

  • 从相关表中选择列。
  • 筛选 相关表中的行。
  • 连接另一个相关表。

多对一关系

基本示例显示了一个多对一关系,其中许多帐户记录可以引用一个联系人记录。 在账户-主联系人多对一关系中定义此信息,该关系具有以下值:

财产 Value 注释
SchemaName account_primary_contact 关系的唯一名称。
ReferencedEntity contact 引用的表格。 多对一关系中的 one。
ReferencedAttribute contactid 引用表的主键。
ReferencingEntity account 包含引用另一张表的查找列的表。 多对一关系中的 many。
ReferencingAttribute primarycontactid 查找列的名称。
RelationshipType OneToManyRelationship 从被引用 (one) 表的角度看,这是一对多关系。
从引用 (many) 表的角度看,这是一多对一关系。

检索关系信息

如果使用 XrmToolBoxFetchXML Builder 或 Power Platform ToolBoxFetchXML Studio 等工具,则可以了解如何选择关系来设置适当的 name、 from属性值和 to 属性值。

还可以使用其他工具和 API 来查找与相应的name、from和to属性值相关的关系数据。 若要了解如何检索此数据,请参阅:

一对多关系

多对一和一对多关系就像一枚硬币的两面。 表之间存在关系,因此使用它的方式取决于哪个表是查询的基表。

您可以使用相同的关联关系,从联系人表中检索与前一个示例相同的数据,但这次是从联系人表的角度出发。 使用相同的 Contact account_primary_contact 一对多关系中的数据,但需根据关联关系的视角调整相关值。

<fetch top='5'>
   <entity name='contact'>
      <attribute name='fullname' />
      <link-entity name='account'
         from='primarycontactid'
         to='contactid'
         alias='account'>
         <attribute name='name' />
      </link-entity>
   </entity>
</fetch>

下表显示了此示例中的 链接实体 属性值:

属性 Value 说明
name account 引用表的逻辑名称
from primarycontactid 引用帐户表中查找列的名称
to contactid 引用的联系人表的主键
alias account 建议为具有一对多关系的 link-entity 设置一个值。 如果未提供别名,系统将生成默认别名。 在此示例中,如果未提供别名,则返回的数据有一个名为account1.name的列。
link-type 未设置 如果未设置值,则默认为 inner

结果包括与使用多对一关系的前一个查询相同的记录和数据。 区别在于 父实体 现在 contact 不是 account。

 -----------------------------------------------------------------
 | fullname                   | account.name                     |
 -----------------------------------------------------------------
 | Susanna Stubberod (sample) | Litware, Inc. (sample)           |
 -----------------------------------------------------------------
 | Nancy Anderson (sample)    | Adventure Works (sample)         |
 -----------------------------------------------------------------
 | Maria Campbell (sample)    | Fabrikam, Inc. (sample)          |
 -----------------------------------------------------------------
 | Sidney Higa (sample)       | Blue Yonder Airlines (sample)    |
 -----------------------------------------------------------------
 | Scott Konersmann (sample)  | City Power & Light (sample)      |
 -----------------------------------------------------------------

多对多关系

多对多关系依赖于 交叉表。 相交表通常只有四列,但其中只有两列很重要。 这两个重要的列对应于参与表的主键列。

例如,TeamMembership 交集表支持 teammembership_association 多对多关系,该关系连接 SystemUser 和 Team 表。 使用此关系,用户可以加入多个团队,团队可以有多个用户。 TeamMembership 包含以下列:systemuserid 和 teamid。

若要使用 teammembership_association 多对多关系检索有关用户及其所属团队的信息,请使用以下 fetchXML 查询:

<fetch top='2'>
   <entity name='systemuser'>
      <attribute name='fullname' />
      <link-entity name='teammembership'
         from='systemuserid'
         to='systemuserid'
         intersect='true' >
         <link-entity name='team'
            from='teamid'
            to='teamid'
            link-type='inner'
            alias='team'>
            <attribute name='name' />
         </link-entity>
      </link-entity>
   </entity>
</fetch>

有两个嵌套链接实体。

  • 第一个列将 systemuser 连接到 teammembership 交集表,其中 systemuserid = systemuserid。
  • 第二个列将 teammembership 交集表连接到 team,其中 teamid = teamid。

结果如下所示:

 --------------------------------------
 | fullname             | team.name   |
 --------------------------------------
 | FirstName LastName   | org26ed931d |
 --------------------------------------
 | # PpdfCDSClient      | org26ed931d |
 --------------------------------------

无关系

可以使用不属于已定义关系的列来指定 from 和 to 属性。

例如,此查询查找帐户记录的 Name 列与联系人记录的 FullName 列匹配的记录对,而不管它们是否在任何查找列中相互引用。

<fetch>
   <entity name='account'>
     <attribute name='name' />
     <link-entity name='contact'
       from='fullname'
       to='name'
       link-type='inner'
       alias='contact'>
       <attribute name='fullname' />
     </link-entity>
   </entity>
 </fetch>

注释

请确保您在 from 和 to 属性中指定的列类型相同,即使它们未参与关系。 如果使用不同类型的列,查询需要类型转换,这可能会影响性能,并且某些列值可能会失败。

您不能在 from 和 to 属性中使用以下列类型:

可以在属性中使用fromto这些列类型,但它们可能会导致性能不佳:

  • 类型为多行文本的列
  • 具有最大长度大于 850 的单行文本类型的列
  • 公式 列
  • 计算 列
  • 逻辑 列

查找不在集合中的记录

可以使用FetchXML创建查询,通过左外部联接返回不属于某个集合的记录。 左外部联接返回满足第一个输入与第二个输入联接条件的每一行。 它还会返回第一个输入中在第二个输入中没有匹配行的任何行。 第二个输入中的非匹配行将作为 null 值返回。

可以在 FetchXML 中通过使用entityname中的来执行左外联接。 该 entityname 属性在条件、筛选条件和嵌套筛选条件中有效。 详细了解链接实体上的筛选器。

例如,以下查询返回没有联系人的所有帐户记录。

<fetch>
   <entity name='account'>
      <attribute name='name' />
      <order attribute='name' />
      <link-entity name='contact'
         from='parentcustomerid'
         to='accountid'
         link-type='outer'
         alias='contact' />
      <filter type='and'>
         <condition entityname='contact'
            attribute='parentcustomerid'
            operator='null' />
      </filter>
   </entity>
</fetch>

以下链接实体类型不直接对应于 T-SQL JOIN 运算符 类型,而是使用 子查询 。 这些类型提供了可用于提高查询性能并定义更复杂的查询的更高级功能。

名称 说明
exists 其变体 inner 可提供性能优势。 在子句中使用where条件。 当结果中不需要父行的多个副本时,请使用此方法。 了解有关 exists 和 in 的更多信息
in 其变体 inner 可提供性能优势。 使用IN条件在where子句中。 当结果中不需要父行的多个副本时,请使用此方法。 了解有关 exists 和 in 的更多信息
matchfirstrowusingcrossapply 其变体 inner 可提供性能优势。 如果只有链接实体中匹配行的单个示例足够,并且结果中父行的多个副本不需要,则使用此类型。 了解有关使用 crossapply 匹配第一行的更多信息

exists 和 in 链接类型是 inner 链接类型的变体。 它们在子句中分别使用不同的条件(EXISTS 和 where),以便查询不返回父行的多个副本。 这两种链接类型都不返回链接实体行的列值。

exists

这些 FetchXML 和 SQL 示例显示了应用的 exists模式。

<fetch>
   <entity name='contact'>
      <attribute name='fullname' />
      <link-entity name='account'
         from='primarycontactid'
         to='contactid'
         link-type='exists'>
         <filter type='and'>
            <condition attribute='statecode'
               operator='eq'
               value='1' />
         </filter>
      </link-entity>
   </entity>
</fetch>

in

这些 FetchXML 和 SQL 示例显示了应用的 in模式。

<fetch>
   <entity name='contact'>
      <attribute name='fullname' />
      <link-entity name='account'
         from='primarycontactid'
         to='contactid'
         link-type='in'>
         <filter type='and'>
            <condition attribute='statecode'
               operator='eq'
               value='1' />
         </filter>
      </link-entity>
   </entity>
</fetch>

使用 exists 或 in 链接类型可以减少中间或最终查询结果的大小。 在同一父行存在许多匹配的链接行时,或多个链接实体用于同一父行时,这种减少特别有帮助。 与 inner 链接类型相比,使用 exists 或 in 链接类型可以提高查询性能,因为查询无需为每个父行返回包含不同关联实体行所有可能排列的笛卡尔积。

通过使用这些链接类型,Dataverse 可能只需要查找每个父行的第一个匹配链接实体行。 这种方法比在 inner 连接中查找关联实体中的所有匹配行更高效。

此链接类型会生成一个 CROSS APPLY 运算符,其子查询采用 top 1 以下模式:

<fetch>
   <entity name='contact'>
      <attribute name='fullname' />
      <link-entity name='account'
         from='primarycontactid'
         to='contactid'
         link-type='matchfirstrowusingcrossapply'>
         <attribute name='accountid' />
         <attribute name='name' />
      </link-entity>
   </entity>
</fetch>

链接 matchfirstrowusingcrossapply 类型与 inner 类型等效,只不过它最多只返回一次父行。 仅当关联实体中存在匹配行时才会返回父行,但与 in 和 exists 类型不同,它会返回关联实体中某条匹配行的列值。 仅当链接实体中的匹配行的单个示例足够,并且结果不需要父行的多个副本时,请使用此类型。

当您使用 matchfirstrowusingcrossapply 链接类型时,通过 Web API 或 SDK Entity.Attributes 集合Keys获取的相关表列值所对应的属性名称与其他类型的连接不同。 通常,这些名称遵循 <tablealias>.<logicalname> 格式。 但是,对于 matchfirstrowusingcrossapply 链接类型,SchemaName 值在使用时不带有表别名前缀。

若将前面的查询示例应用于任何其他链接类型,这些属性或键的名称通常如下所示:

  • fullname
  • contactid
  • account1.accountid
  • account1.name

但是,通过使用 matchfirstrowusingcrossapply 链接类型,属性或键具有以下名称:

  • fullname
  • contactid
  • AccountId
  • Name

后续步骤

了解如何对行进行排序。