使用通用 FetchXML 扩展 Universal Resource Scheduling

UFX 是一种高级查询语言,供您使用动态 FetchXML 查询数据,调整并准备结果数据供 Universal Resource Scheduling (URS) 解决方案使用。 可使用此查询语言创建自定义查询以自定义和扩展日程安排板和日程安排助理筛选器,以便满足组织的特定业务需求。

UFX 中包含两个组件:UFX 包和 UFX 查询。

简单 UFX 包

UFX 包中包含静态类型数据。 它在内存中表示为包含键和值的字典。 可序列化为 JSON 和 XML。 通过让数据类型化,UFX 查询可以从中查询数据,并让客户端 UI 与其绑定。

因为实践和性能原因,将对 Dynamics 365 应用 SDK Entity 对象实施内存内包。

包含两个值的示例包。

在内存中:

关键字 type
名称 John 字符串
年龄 36 int

在 JSON 中:

{
    "name": "John",
    "age": 36
}

在 XML 中:

<bag>
    <name ufx-type="string">John</name>
    <age ufx-type="int">36</age>
</bag>

UFX 支持的类型

UFX 包中可以包含多种类型的值。 这些值分为三种类型的类:

类别
简单类型 bool (Boolean)int (Int32)long (Int64)double (Double)decimal (Decimal)datetime (DateTime)guid (Guid)string (String)
特定于 Dynamics 365 的简单类型:money (Money)option (OptionSet)lookup (EntityReference)
其他包 bag (Entity)
包列表 list (EntityCollection)

下面是其中包含更多类型的示例 JSON 包:

{
    "citizen": true,          // implicit bool
    
    "age": 36,                // explicit int
    "age@ufx-type": "int",

    "name": {                 // nested bag
        "first": "John",
        "last": "Doe"
    },

    "children": [             // list of bags
        { "name": "Sam" },
        { "name": "Judy" }
    ]
}

XML 格式的示例包:

<bag>
    <citizen ufx-type="bool">true</citizen>

    <age ufx-type="int">36</age>

    <name ufx-type="bag">
        <first ufx-type="string">John</first>
        <last ufx-type="string">Doe</last>
    </name>

    <children ufx-type="list">
        <bag>
            <name ufx-type="string">Sam</name>
        </bag>
        <bag>
            <name ufx-type="string">Judy</name>
        </bag>
    </children>
</bag>

UFX 查询简介

UFX 查询被编写为基于 XML 的UFX 包。 此包中的属性可包含 UFX 指令,用于动态查询数据。 UFX 查询对内存内对象执行,而不是对 XML 执行。 只有指令才以 XML 格式编写。 其输出可以序列化为 JSON 或 XML。

以下 UFX 查询定义包含 source UFX 指令的包中的 accounts 属性。 这将导致 Dynamics 365 执行内联 FetchXML,并且 accounts 属性成为包列表,即 EntityCollection,其中的每个包是来自 Dynamics 365 的一个客户类型实例。

<bag xmlns:ufx="https://schemas.microsoft.com/dynamics/2017/universalfetchxml">
    <accounts ufx:source="fetch">
        <fetch top="10">
            <entity name="account" />
        </fetch>
    </accounts>
</bag>

UFX 查询按照顺序处理,其中可以包含多个 FetchXML 查询。

下面是上一个序列化 XML 的 UFX 查询的结果的一个片段。 可以看到一些值有元数据,用于进一步加以描述。

<bag>
  <accounts ufx-type="list">
    <bag ufx-id="166e39dd-34a1-e611-8111-00155d652f01" ufx-logicalname="account">
      <accountid ufx-type="guid">166e39dd-34a1-e611-8111-00155d652f01</accountid>
      <accountnumber ufx-type="string">ABSS4G45</accountnumber>
      <name ufx-type="string">Fourth Coffee (sample)</name>
      <statecode ufx-type="option" ufx-formatvalue="Active">0</statecode>
      <websiteurl ufx-type="string">https://www.fourthcoffee.com/</websiteurl>
      <primarycontactid ufx-type="lookup" ufx-formatvalue="Yvonne McKay (sample)" ufx-logicalname="contact">7c6e39dd-34a1-e611-8111-00155d652f01</primarycontactid>
      ...
    </bag>
    <bag ufx-type="bag" ufx-id="186e39dd-34a1-e611-8111-00155d652f01" ufx-logicalname="account">
      <accountid ufx-type="guid">186e39dd-34a1-e611-8111-00155d652f01</accountid>
      <accountnumber ufx-type="string">ACTBBDC3</accountnumber>
      <name ufx-type="string">Litware, Inc. (sample)</name>
      <statecode ufx-type="option" ufx-formatvalue="Active">0</statecode>
      <websiteurl ufx-type="string">https://www.litwareinc.com/</websiteurl>
      <primarycontactid ufx-type="lookup" ufx-formatvalue="Susanna Stubberod (sample)" ufx-logicalname="contact">7e6e39dd-34a1-e611-8111-00155d652f01</primarycontactid>
      ...
    </bag>
    ...
  </accounts>
</bag>

select UFX 指令采用 XPath 表达式来从当前包中选择值。

<bag xmlns:ufx="https://schemas.microsoft.com/dynamics/2017/universalfetchxml">
    <accounts ufx:source="fetch">
        <fetch top="10">
            <entity name="account" />
        </fetch>
    </accounts>

    <first_account_name ufx:select="accounts/bag[1]/name" />

    <!-- null values remove properties from the bag -->
    <accounts ufx:select="$null" />
</bag>

XML 格式的结果包:

<bag>
    <first_account_name ufx-type="string">Fourth Coffee (sample)</first_acount_name>
</bag>

当然,UFX 查询最强大的功能是可以根据输入数据动态生成 FetchXML。

在下面的示例中,将按用户提供并通过 XPath $input 变量以 UFX 包的形式提供的值搜索帐户。 请注意 condition 元素中的 UFX ifvalue 指令。

<bag xmlns:ufx="https://schemas.microsoft.com/dynamics/2017/universalfetchxml">
    <accounts ufx:source="fetch">
        <fetch top="10">
            <entity name="account">
                <filter>
                    <condition attribute="name" operator="like" ufx:if="$input/NameFilter">
                        <ufx:value select="$input/NameFilter" attribute="value" />
                    </condition>
                </filter>
            </entity>
        </fetch>
    </accounts>
</bag>

如果输入包中的 NameFilter 属性包含 %city%,则生成且由 Dynamics 365 执行的 FetchXML 条件如下所示。

<condition attribute="name" operator="like" value="%city%" />

键、值和元数据

UFX 包中包含键和值,其中一些值由更多元数据来描述这些值。

例如,类型为 lookup (EntityReference) 的值。 通过 FetchXML 从 Dynamics 365 查询时,将返回实体的逻辑名称,以及格式化的记录显示名称。 UFX 包将这些额外信息保持为附加到主值的元数据。

包含元数据的 lookup 序列化为 JSON,如下所示:

{
    "primarycontactid": "7e6e39dd-34a1-e611-8111-00155d652f01",
    "primarycontactid@ufx-type": "lookup",
    "primarycontactid@ufx-logicalname": "contact",
    "primarycontactid@ufx-formatvalue": "Susanna Stubberod (sample)"
}

在 XML 中:

<primarycontactid ufx-type="lookup" ufx-formatvalue="Susanna Stubberod (sample)" ufx-logicalname="contact">7e6e39dd-34a1-e611-8111-00155d652f01</primarycontactid>

通过 Dynamics 365 的 XPath 数据

通过将数据设置为 UFX 包格式,UFX 查询可以以结构化格式查看这些数据,以及使用 XPath 遍历这些数据并从中选择值。

UFX 指令中指定的 XPath 表达式将包中的数据视为类似 XML 序列化形式的包结构。 但是,这些数据存储在内存内 .NET 对象中(在 EntityEntityCollection 类型的实例中),而不是存储在 XML 文档中。

附录 A:UFX 类型参考

注意:所有 UFX 类型都支持 ufx-typeufx-formatvalue 元数据。 下表中每种类型的旁边介绍了更多元数据。

UFX 名称 属性类型代码 .NET 名称 UFX 元数据
bool 布尔值 布尔值
int 整数 Int32
长整型 Bigint Int64
双精度 Double Double
十进制 十进制 十进制
日期时间 DateTime DateTime
guid Uniqueidentifier GUID
字符串 Memo 字符串
货币 Money Money
选项 Picklist OptionSetValue
查找 查找 EntityReference ufx-logicalname
不适用 实体 ufx-id
ufx-logicalname
list 不适用 EntityCollection
不适用 不适用 AliasedValue ufx-aliasentity
ufx-aliasattribute

附录 B:UFX 查询指令

可对包属性和 FetchXML 查询的 XML 元数据使用 UFX 指令。

UFX 包指令

属性 Value 说明
ufx:if XPath 测试 XPath 表达式,并仅在测试返回 true 时才处理属性
ufx:source fetch 执行内联 <fetch> XML 元素,并将结果分配给属性
ufx:select XPath 执行 XPath 表达式,并将结果分配给属性
查询 baglist 时,可指定 XML 格式的可选子 bag 以转换 XPath 表达式的结果

UFX FetchXML 指令

元素 属性 Value 说明
所有元素 ufx:if XPath 测试 XPath 表达式,并仅在测试成功时才发出 XML 元素
ufx:apply select XPath 检查 XPath 表达式返回的节点集,并为每个节点输出一次子 XML 元素
ufx:value select XPath 执行 XPath 表达式并在当前 XML 元素中输出结果
ufx:value attribute 属性名称 将 XPath 表达式结果分配给当前 XML 元素中的指定属性名称

附录 C:UFX XPath 函数

除了 XPath 中的本机可用函数,UFX 还会添加一些新函数。

datetime()

  • datetime():返回 UTC 格式的当前时间

list()

  • list(bag | list, ...[bag | list]):采用一些 baglist 值作为输入,并将这些值简单化为一个 list

lookup-to-list()

  • lookup-to-list(lookup, ...[lookup]):采用一些 lookup 值,将其中的每一个转换为包含 ufx-idufx-logicalname 元数据集的 bag,然后简单化为一个 list

option-to-list()

  • option-to-list(option, ...[option]):采用一些 option 值,将其中的每一个转换为包含一个 option 属性的 bag,然后简单化为一个 list

order()

  • order(list, string, bool):按每个包中的属性为列表排序。 此属性在参数 2 中指定,后续属性在参数 3 中指定。
  • order(list, list):按参数 2 中指定为列表的多个排序顺序为列表排序。 第二个列表中的每个 bag 都有一个 namedescending 属性

iif()

  • iif(any, any, any):如果参数 1 为 true,则返回参数 2,否则返回参数 3

附录 D:UFX XPath 变量

姓名 说明
$input 可供包含输入值的 UFX 查询使用的 bag
$null 一个空常数。 选择属性中的 $null 将从包中删除该属性
$current 引用 UFX 查询正在处理的当前包

另请参阅

了解与自定义 Universal Resource Scheduling 中的资源匹配

Universal Resource Scheduling 扩展性发行说明