Расширение Universal Resource Scheduling с использованием универсального языка FetchXML
UFX является расширенным языком запросов, который позволяет запросить данные с использование динамического языка FetchXM, формировать и подготовить получающиеся в результате данные для потребления решением Universal Resource Scheduling (URS). Этот язык запросов позволяет создавать настраиваемые запросы для настройки и расширения фильтров доски расписания и помощника по расписанию для удовлетворения уникальных бизнес-целей организации.
UFX состоит из двух компонентов: сумка UFX и запрос UFX.
Простая сумка UFX
Сумка UFX содержит определенные статические типизованные данные. В памяти она представляла как словарь с ключами и значениями. Ее можно сериализовать в JSON и XML. Типизованные данные позволяют запросу UFX запрашивать данные из него, а клиенту интерфейса пользователя задавать привязку к нему.
По практическим причинам и причинам производительности сумка в памяти реализована на основе объекта
Entity
пакета SDK приложений Dynamics 365.
Пример сумки, содержащей два значения.
В памяти:
key | значение | тип |
---|---|---|
name | Иван | строка |
возраст | 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 на основе XML. Свойства в сумке могут содержать директивы UFX для динамического запроса данных. Запрос UFX выполняется на объектах в памяти, а не в XML. Только директивы записываются в XML. Их выходные данные можно сериализовывать в JSON или XML.
Следующий запрос UFX определяет свойство accounts
в сумке с директивой UFX source
. Это приводит к исполнению встроенного языка FetchXML в Dynamics 365, и свойство 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>
Директива UFX select
принимает выражение 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 позволяют запросу UFX видеть их в структурированном формате и использовать директиву XPath для обхода данных и выбора значений из них.
Выражение XPath, указанное в директиве UFX, видит данные в сумке подобно структуре сумки в XML-сериализованной форме. Однако данные сохраняются в объектах .NET в памяти (в случаях типов Entity
и EntityCollection
), а не в документах XML.
Приложение A. Справочник по типам UFX
Примечание. Все типы UFX поддерживают метаданные ufx-type
и ufx-formatvalue
. Дополнительные метаданные описаны рядом с каждым типом в таблице ниже.
Имя UFX | Код типа атрибута | Имя .NET | Метаданные UFX |
---|---|---|---|
bool | Логическое | Логическое | |
целое | Целое число | Int32 | |
long | BigInt | Int64 | |
double | Double | Double | |
десятичное | Десятичное число | Десятичное число | |
Дата/время | Дата и время | Дата и время | |
guid | Uniqueidentifier | GUID | |
строка | Памятка | Строка | |
деньги | Денежная сумма | Денежная сумма | |
option | Список выбора | OptionSetValue | |
поиск | Поиск | EntityReference | ufx-logicalname |
bag | Н/Д | Сущность | ufx-id ufx-logicalname |
list | Н/Д | EntityCollection | |
Н/Д | Н/Д | AliasedValue | ufx-aliasentity ufx-aliasattribute |
Приложение B. Директивы запроса UFX
Директивы UFX могут использоваться в свойствах сумки и элементах XML запроса FetchXML.
Директивы сумки UFX
Атрибут | Value | Описание |
---|---|---|
ufx:if |
XPath | Проверяет выражение XPath и обрабатывает свойство только в том случае, если проверка возвращает истинное значение |
ufx:source |
fetch |
Выполняет встроенный элемент XML <fetch> и назначает результат свойству |
ufx:select |
XPath | Выполняет выражение XPath и назначает результат свойству При запросе bag или list необязательный дочерний элемент bag в форме XML может быть указан для преобразования результата выражения 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
UFX добавляет несколько новых функций помимо функций, доступным изначально в XPath.
datetime()
- datetime(): возвращает текущее время в формате UTC
list()
- list(bag | list, ...[bag | list]): принимает ряд значений
bag
илиlist
в качестве входных данных и преобразует их в один элементlist
lookup-to-list()
- lookup-to-list(lookup, ...[lookup]): принимает несколько значений
lookup
, преобразует каждое из них в элементbag
с установленными даннымиufx-id
иufx-logicalname
, затем преобразует их в один элементlist
option-to-list()
- option-to-list(option, ...[option]): принимает несколько значений
option
, преобразует каждое из них в элементbag
с одним свойствомoption
, затем преобразует их в один элементlist
order()
- order(list, string, bool): упорядочивает список по свойству в каждой сумке. Свойство указывается в аргументе 2, по уменьшению указывается в аргументе 3.
- order(list, list): упорядочивание списка с несколькими порядками сортировки, указанными как список в аргументе 2. Каждый
bag
во втором списке может иметь свойствоname
иdescending
iif()
- iif(любой, любой, любой): если аргумент 1 равен true, возвращается аргумент 2, в противном случае возвращается аргумент 3
Приложение D. Переменные UFX XPath
Имя | Описание |
---|---|
$input | Элемент bag , доступный в запросе UFX с входными значениями |
$null | Константа NULL. При выборе $null в свойстве это свойство удаляется из сумки |
$current | Ссылка на текущую сумку, обрабатываемую запросом UFX |
См. также
Общие сведения и настройка сопоставления ресурсов в Universal Resource Scheduling
Заметки о выпуске расширяемости Universal Resource Scheduling