Universal FetchXML для расширения универсального планирования ресурсов

Universal FetchXML (UFX) — это усовершенствованный язык запросов, который позволяет запрашивать данные с помощью динамического FetchXML, формировать и подготавливать полученные данные для использования решением Universal Resource Scheduling (URS). Этот язык запросов позволяет создавать пользовательские запросы для настройки и расширения фильтров доски расписания и помощника по расписанию в соответствии с уникальными бизнес-потребностями организации.

UFX состоит из двух компонентов: UFX bag и UFX query.

Простая сумка UFX

Сумка UFX содержит статические данные. В памяти он моделирует словарь с ключами и значениями. Он может быть сериализован в JSON и XML. Наличие типизированных данных позволяет запросу UFX запрашивать данные из них, а пользовательский интерфейс клиента — привязываться к ним.

По практическим соображениям и из соображений производительности контейнер в памяти реализован поверх объекта пакета SDK Entity для приложений Dynamics 365.

Пакет с образцами, содержащий два значения.

На память:

ключ ценность тип
имя Джон струна
возраст 36 инт

В ФОРМАТЕ 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-запросы записываются в виде UFX Bags на основе XML. Свойства в пакете могут содержать директивы UFX для динамического запроса данных. UFX-запрос выполняется с объектами в памяти, а не с XML. Только директивы написаны в формате XML. Его выходные данные могут быть сериализованы в JSON или XML.

Следующий запрос UFX определяет свойство accounts в контейнере с помощью директивы source UFX. В результате 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.

Ниже приведен фрагмент результата предыдущего запроса UFX, сериализованного в XML. Обратите внимание, что некоторые значения имеют метаданные, более подробно описывающие их.

<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 на основе входных данных.

В следующем примере мы ищем счета по значению, предоставленному пользователем и доступному в виде пакета UFX с помощью переменной XPath $input . Обратите внимание на директивы UFX if и value на элементе condition .

<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% созданное условие FetchXML, выполненное Dynamics 365, выглядело бы следующим образом.

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

Ключи, значения и метаданные

Сумка UFX содержит ключи и значения, причем некоторые значения имеют больше метаданных для их описания.

Примером может быть значение типа lookup (EntityReference). При запросе из Dynamics 365 через FetchXML он возвращает логическое имя сущности и отформатированное отображаемое имя записи. Сумка UFX сохраняет эту дополнительную информацию в виде метаданных, прикрепленных к основному значению.

Сериализованный в JSON, файл lookup с метаданными выглядит следующим образом:

{
    "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>

XPath над данными Dynamics 365

Наличие типизированных данных в UFX Bag позволяет UFX Query видеть их в структурированном формате и использовать XPath для обхода данных и выбора значений из них.

Выражение XPath, указанное в директиве UFX, видит данные в контейнере аналогично структуре контейнера в сериализованном формате XML. Однако данные хранятся в объектах .NET в памяти (в экземплярах и Entity типахEntityCollection), а не в документах XML.

Справочник по типам UFX

Все типы UFX поддерживают ufx-type метаданные and ufx-formatvalue . Дополнительные метаданные описаны рядом с каждым типом.

Название UFX Код типа атрибута Имя .NET Метаданные UFX
булевая переменная (bool) Булев Булев
инт Целое число Int32
долго БигИнт Int64
двойной Двойной Двойной
десятичная система Десятичное число Десятичное число
дата/время дата и время дата и время
гид Уникальный идентификатор Гид
струна Памятка Струна
деньги Деньги Деньги
Опция Список выбора OptionSetValue (ПараметрУстановитьЗначение)
Поиска Поиск EntityReference ufx-logicalname
сумка Не применимо Объект ufx-id
ufx-logicalname
список Не применимо EntityCollection (EntityCollection)
Не применимо Не применимо AliasedValue (ПсевдонимноеЗначение) ufx-aliasentity
ufx-aliasattribute

Директивы запросов UFX

Директивы UFX могут использоваться для свойств bag и для XML-элементов запроса FetchXML.

Директивы по сумкам UFX

Свойство Ценность Описание
ufx:if XPath Проверяет выражение XPath и обрабатывает свойство только в том случае, если тест возвращает true
ufx:source fetch Выполняет встроенный <fetch> элемент XML и присваивает результат свойству
ufx:select XPath Выполняет выражение XPath и присваивает результат свойству
При запросе на дочерний baglist или необязательный дочерний элемент bag в XML-форме может быть указан для преобразования результата XPath-выражения

Директивы UFX FetchXML

Элемент Свойство Ценность Описание
Все элементы ufx:if XPath Проверяет выражение XPath и выдает элемент XML только в случае успешного выполнения тестов
ufx:apply select XPath Цикл по набору узлов, возвращенному выражением XPath, и вывод дочерних элементов XML по одному разу для каждого узла
ufx:value select XPath Выполняет выражение XPath и выводит результат в текущем элементе XML
ufx:value attribute Имя атрибута Присваивает результат выражения XPath указанному имени атрибута текущего элемента XML

Функции UFX XPath

UFX добавляет множество новых функций в дополнение к тем, которые изначально доступны в XPath.

datetime()

  • datetime(): Возвращает текущее время в формате UTC

list()

  • list(bag | list, ... [bag | list]): Принимает ряд значений bag or list в качестве входных данных и объединяет их в одно list

поиск в список()

  • lookup-to-list(lookup, ... [lookup]): Принимает ряд lookup значений, преобразует каждое из них в a bag с набором ufx-id метаданных and ufx-logicalname и преобразует их в одно list

опция-к-листу()

  • option-to-list(опция, ... [option]): Принимает ряд option значений, преобразует каждое из них в a bag с одним option свойством и преобразует их в одно list

order()

  • order(list, string, bool): Упорядочивает список по свойству в каждой сумке. Свойство указывается в аргументе 2, по убыванию указывается в аргументе 3.
  • order(list, list): Упорядочить список по нескольким порядкам сортировки, указанным в виде списка в аргументе 2. Каждый bag из второго списка может иметь свойство и namedescending

iif()

  • iif(any, any, any): Если аргумент 1 истинен, возвращает аргумент 2, в противном случае возвращает аргумент 3

Переменные UFX XPath

Имя Описание
$input Доступный bag для UFX запрос с входными значениями
$null Нулевая константа. При выборе $null объекта недвижимости он удаляется из корзины
$current Ссылка на текущую сумку, которую обрабатывает запрос UFX

Дополнительные ресурсы

Понимание и настройка сопоставления ресурсов в универсальном планировании ресурсов