DataService. Использование макросов
Glossary Item Box
Общие положения
Во время выполнения операций службы DataService часто необходимо фильтровать данные по некоторому периоду времени, например, текущей неделе или ближайшему часу. Для того чтобы облегчить работу с такого рода задачами и избежать повторного создания пользовательских методов, предусмотрены макросы. Макросы реализованы как специальные классы, которые предназначены для вычисления типовых значений в выражениях запросов, например для вычисления даты начала и окончания текущего полугодия. Макросы можно использовать только в случае, если тип выражения запроса — функция. Подробнее о типах выражений запросов можно узнать из статьи DataService. Фильтрация данных.
Типы макросов
При создании запросов к службе DataService могут использоваться как параметризированные, т.е. требующие аргумент, так и непараметризированные макросы. Типы макросов, которые можно использовать в выражениях запросов, определены перечислением EntitySchemaQueryMacrosType в пространстве имен Terrasoft.Core.Entities. Значения перечисления типов макросов и их описание приведены в табл. 1.
Табл. 1. — Значения перечисления EntitySchemaQueryMacrosType и их описание.
Макрос | Значение | Описание |
---|---|---|
CurrentHalfYear | 16 | Текущее полугодие. |
CurrentHour | 21 | Текущий час. |
CurrentMonth | 10 | Текущий месяц. |
CurrentQuarter | 13 | Текущий квартал. |
CurrentUser | 1 | Текущий пользователь. |
CurrentUserContact | 2 | Контакт текущего пользователя. |
CurrentWeek | 7 | Текущая неделя. |
CurrentYear | 19 | Текущий год. |
DayOfMonth | 28 | День месяца. Требует параметризации. |
DayOfWeek | 29 | День недели. Требует параметризации. |
Hour | 30 | Час. Требует параметризации. |
HourMinute | 31 | Время. Требует параметризации. |
Month | 32 | Месяц. Требует параметризации. |
NextHalfYear | 17 | Следующее полугодие. |
NextHour | 22 | Следующий час. |
NextMonth | 11 | Следующий месяц. |
NextNDays | 24 | Следующие N дней. Требует параметризации. |
NextNHours | 26 | Следующие N часов. Требует параметризации. |
NextQuarter | 14 | Следующий квартал. |
NextWeek | 8 | Следующая неделя. |
NextYear | 23 | Следующий год. |
None | 0 | Тип макроса не определен. |
PreviousHalfYear | 15 | Предыдущее полугодие. |
PreviousHour | 20 | Предыдущий час. |
PreviousMonth | 9 | Предыдущий месяц. |
PreviousNDays | 25 | Предыдущие N дней. Требует параметризации. |
PreviousNHours | 27 | Предыдущие N часов. Требует параметризации. |
PreviousQuarter | 12 | Предыдущий квартал. |
PreviousWeek | 6 | Предыдущая неделя. |
PreviousYear | 18 | Предыдущий год. |
Today | 4 | Сегодня. |
Tomorrow | 5 | Завтра. |
Year | 33 | Год. Требует параметризации. |
Yesterday | 3 | Вчера. |
Пример использования макросов
Описание кейса
Необходимо создать консольное приложение, которое, используя службу DataService, прочитает записи раздела [Контакты] со следующими колонками:
- Id;
- ФИО;
- Дата рождения.
При этом необходимо отфильтровать данные таким образом, чтобы были прочитаны только те контакты, у которых год рождения равен 1992.
Пример реализации
Полностью исходный код выполнения данного примера можно посмотреть в репозитории GitHub здесь.
Алгоритм реализации кейса
1. Создать и настроить проект консольного приложения C#, выполняющий чтение записей
Для выполнения этого шага последовательности реализации кейса необходимо выполнить пример чтения записей в стороннем приложении, изложенный в статье "DataService. Чтение записи. Пример".
Результат реализации экземпляра класса запроса на чтение записей с нужными колонками в сокращенной форме:
// Экземпляр класса запроса. var selectQuery = new SelectQuery() { // Название корневой схемы. RootSchemaName = "Contact", // Добавление колонок в запрос. Columns = new SelectQueryColumns() { // Коллекция колонок. Items = new Dictionary<string, SelectQueryColumn>() { //Колонка [ФИО]. { // Ключ. "Name", // Значение. new SelectQueryColumn() { // Выражение, задающее тип колонки. Expression = new ColumnExpression() { // Тип выражения — колонка схемы. ExpressionType = EntitySchemaQueryExpressionType.SchemaColumn, // Путь к колонке. ColumnPath = "Name" } } }, // Колонка [Количество активностей]. { "ActivitiesCount", new SelectQueryColumn() { Expression = new ColumnExpression() { // Тип выражения — вложенный запрос. ExpressionType = EntitySchemaQueryExpressionType.SubQuery, // Путь к колонке относительно корневой схемы. ColumnPath = "[Activity:Contact].Id", // Тип функции — агрегирующая. FunctionType = FunctionType.Aggregation, // Тип агрегации — количество. AggregationType = AggregationType.Count } } } } } };
2. Добавить реализацию фильтра c макросом
Для того чтобы отфильтровать необходимые данные, необходимо создать экземпляр класса коллекции фильтров Filters, заполнить необходимые свойства значениями, а затем ссылку на этот экземпляр передать в свойство Filters экзепляра класса запроса, созданного на предыдущем шаге.
Пример реализации класса коллекции фильтров:
// Фильтры запроса. var selectFilters = new Filters() { // Тип фильтра — группа. FilterType = Terrasoft.Nui.ServiceModel.DataContract.FilterType.FilterGroup, // Коллекция фильтров. Items = new Dictionary<string, Filter> { // Фильтрация по году рождения. { // Ключ. "FilterYear", // Значение. new Filter { // Тип фильтра — фильтр сравнения. FilterType = Terrasoft.Nui.ServiceModel.DataContract.FilterType.CompareFilter, // Тип сравнения — равенство. ComparisonType = FilterComparisonType.Equal, // Выражение, подлежащее проверке. LeftExpression = new BaseExpression() { // Тип выражения — колонка схемы. ExpressionType = EntitySchemaQueryExpressionType.SchemaColumn, // Путь к схеме. ColumnPath = "BirthDate" }, // Выражение, с которым сравнивается проверяемое значение. RightExpression = new BaseExpression { // Тип выражения — функция. ExpressionType = EntitySchemaQueryExpressionType.Function, // Тип функции — макрос. FunctionType = FunctionType.Macros, // Тип макроса — год. MacrosType = EntitySchemaQueryMacrosType.Year, // Аргумент функции. FunctionArgument = new BaseExpression { // Тип выражения, определяющего аргумент — параметр. ExpressionType = EntitySchemaQueryExpressionType.Parameter, // Инициализация параметра. Parameter = new Parameter { // Тип параметра — целое число. DataValueType = DataValueType.Integer, // Значение параметра. Value = "1992" } } } } } } }; // Добавление фильтров в запрос. selectQuery.Filters = selectFilters; // Сериализация экземпляра класса запроса на чтение в JSON-строку. var json = new JavaScriptSerializer().Serialize(selectQuery);
Коллекция содержит единственный фильтр с ключом "FilterYear". Поскольку необходимо из коллекции записей выбрать только те, у которых год рождения контакта равен 1992, то тип фильтра устанавливается как фильтр сравнения, а тип сравнения — равенство значений. В качестве выражения, подлежащего проверке, устанавливается значение колонки [Дата рождения], а в качестве выражения, с которым сравнивается проверяемое выражение — функция-макрос.
В данном случае использовать макрос удобно потому, что дата рождения хранится в базе данных в формате "ГГГГ-ММ-ДД", где "ГГГГ" — год, "ММ" — месяц, а "ДД" — день. Макрос автоматически определяет год из этого значения, следовательно, разработчику нет необходимости самостоятельно писать дополнительный программный код.
Поскольку макрос EntitySchemaQueryMacrosType.Year является параметрическим, то необходимо инициализировать свойство FunctionArgument, которому присваивается ссылка на экземпляр класса BaseExpression. В нем и определяется целочисленный параметр со значением 1992.
Полностью исходный код выполнения данного примера можно посмотреть в репозитории GitHub здесь.