Отфильтровать записи раздела с использованием макроса

Сложный

Пример. Создать консольное приложение, которое, используя класс SelectQuery, прочитает записи раздела Контакты (Contacts). Отобразить колонки:

  • Id.
  • ФИО (Name).
  • Дата рождения (Birthday).

Отфильтровать данные таким образом, чтобы были прочитаны только те контакты, у которых год рождения равен "1992".

Реализовать фильтр с макросом 

Предварительно выполните пример чтения записей в стороннем приложении, описанный в статье Добавить кнопку для чтения записей раздела [Контакты].

Результат реализации экземпляра класса запроса на чтение записей в сокращенной форме представлен ниже.

SelectQuery()
/* Экземпляр класса запроса. */
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
                    }
                }
            }
        }
    }
};

Чтобы реализовать фильтр c макросом:

  1. Создайте экземпляр класса коллекции фильтров Filters.
  2. Заполните необходимые свойства значениями.
  3. В свойство 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, то тип фильтра устанавливается как фильтр сравнения, а тип сравнения — равенство значений. В качестве выражения, подлежащего проверке, устанавливается значение колонки Дата рождения (Birthday), а в качестве выражения, с которым сравнивается проверяемое выражение — функция-макрос.

    В данном случае использовать макрос удобно потому, что дата рождения хранится в базе данных в формате ГГГГ-ММ-ДД. Макрос автоматически определяет год из этого значения, следовательно, разработчику нет необходимости самостоятельно писать дополнительный программный код.

    Поскольку макрос EntitySchemaQueryMacrosType.Year является параметрическим, то необходимо инициализировать свойство FunctionArgument, которому присваивается ссылка на экземпляр класса BaseExpression. В нем и определяется целочисленный параметр со значением "1992".