Работа с фильтрами EntitySchemaQuery
Glossary Item Box
Общие сведения
Фильтр — это набор условий, применяемых при отображении данных запроса. В терминах SQL фильтр представляет собой отдельный предикат (условие) оператора WHERE.
Любой фильтр как условие запроса имеет свою структуру (рис. 1).
Рис. 1. Структура фильтра EntitySchemaQuery
Filter = {[AggregationType] {<LeftExpression> | <LeftExpressionColumnPath>} <ComparisonType> {{<RightExpression> | {<RightExpressionColumnPath>,...}} | {<Macros>, [MacrosValue]}} }
Основные составляющие фильтра EntitySchemaQuery:
- AggregationType — тип агрегирующей функции, которая применяется к выражению в левой части условия. Необязательная составляющая фильтра. Задается значениями перечисления FilterAggregationType.
- LeftExpression — выражение в левой части фильтра. Задается экземпляром типа EntitySchemaQueryExpression.
- LeftExpressionColumnPath — путь к колонке, которая содержит выражение левой части фильтра. Задается строковым значением.
- ComparisonType — тип сравнения выражений в фильтре. Задается значением перечисления FilterComparisonType.
- RightExpression — выражение в правой части фильтра. Задается экземпляром типа EntitySchemaQueryExpression.
- RightExpressionColumnPath — путь к колонке, которая содержит выражение правой части фильтра. Задается строковым значением.
- Macros — макрос, который возвращает выражение для правой части фильтра. Задается значением перечисления EntitySchemaQueryMacrosType.
- MacrosValue — значение, которое передается в качестве параметра макросу Macros. Необязательный параметр. Задается экземплярами значений различных типов в зависимости от типа вызываемого макроса.
Создание и применение фильтров в EntitySchemaQuery
Для создания простого фильтра (рис. 1) в EntitySchemaQuery используется метод CreateFilter(), который возвращает экземпляр типа EntitySchemaQueryFilter. Для этого метода в EntitySchemaQuery реализован ряд перегрузок, что позволяет создавать фильтры с различными исходными параметрами.
Наряду с простыми фильтрами, в EntitySchemaQuery реализованы методы создания фильтров специального вида (табл. 1).
Табл. 1. — Методы EntitySchemaQuery для создания фильтров специального вида
Метод создания фильтра | Описание |
---|---|
CreateFilterWithParameters() | Создает параметризированный фильтр для выборки записей по определенным условиям. Перегруженный метод. |
CreateIsNullFilter() | Создает фильтр сравнения типа [Является null в базе данных]. |
CreateIsNotNullFilter() | Создает фильтр сравнения типа [Не является null в базе данных]. |
СreateExistsFilter() | Создает фильтр сравнения типа [Существует по заданному условию]. |
CreateNotExistsFilter() | Создает фильтр сравнения типа [Не существует по заданному условию]. |
Экземпляр EntitySchemaQuery имеет свойство Filters, которое представляет собой коллекцию фильтров данного запроса (экземпляр класса EntitySchemaQueryFilterCollection, который, в свою очередь, представляет собой классическую типизированную коллекцию элементов IEntitySchemaQueryFilterItem). Для того, чтобы добавить фильтр в запрос, необходимо:
- создать экземпляр фильтра для данного запроса (методы CreateFilter(), методы создания фильтров специального вида);
- добавить созданный экземпляр фильтра в коллекцию фильтров запроса (метод Add() коллекции).
По умолчанию все фильтры, добавляемые в коллекцию Filters, объединяются между собой логической операцией AND. Свойство LogicalOperation коллекции Filters позволяет пользователю указать логическую операцию, которой необходимо объединять фильтры. Свойство принимает значения из перечисления LogicalOperationStrict.
В запросах EntitySchemaQuery реализована возможность управления фильтрами, участвующими в построении результирующего набора данных. Каждый элемент коллекции Filters имеет свойство IsEnabled, которое определяет, участвует ли данный элемент в построении результирующего запроса (true — участвует, false — не участвует). Аналогичное свойство IsEnabled также определено для всей коллекции Filters. Установив это свойство в false, можно полностью отключить фильтрацию для запроса, при этом коллекция фильтров запроса останется неизменной. Таким образом, изначально сформировав коллекцию фильтров запроса, в дальнейшем можно использовать различные комбинации для фильтрации этого запроса, не внося изменений в саму коллекцию.
Формирование путей колонок в фильтрах EntitySchemaQuery формируется согласно правилам, описанным в статье Корневая схема. Построение путей к колонкам.
Пример 1
Пример управления фильтрами в запросе.
// Создание экземпляра запроса с корневой схемой "City". var esqCities = new EntitySchemaQuery(UserConnection.EntitySchemaManager, "City"); esqCities.AddColumn("Name"); // Создание экземпляра первого фильтра. var esqFirstFilter = esqCities.CreateFilterWithParameters(FilterComparisonType.Equal, "Name", "Киев"); // Создание экземпляра второго фильтра. var esqSecondFilter = esqCities.CreateFilterWithParameters(FilterComparisonType.Equal, "Name", "Москва"); // Фильтры в коллекцию фильтров запроса будут объединяться логическим оператором OR. esqCities.Filters.LogicalOperation = LogicalOperationStrict.Or; // Добавление созданных фильтров в коллекцию запроса. esqCities.Filters.Add(esqFirstFilter); esqCities.Filters.Add(esqSecondFilter); // В данную коллекцию попадут объекты - результаты запроса, отфильтрованные по двум фильтрам. var entities = esqCities.GetEntityCollection(UserConnection); // Для второго фильтра указывается, что он не будет участвовать в построении результирующего запроса. // При этом данный фильтр не удаляется из коллекции фильтров запроса. esqSecondFilter.IsEnabled = false; // Обновляет экземпляр Select, ассоциированный с запросом, в соответствии с актуальным набором фильтров. esqCities.ResetSelectQuery(); // В данную коллекцию попадут объекты - результаты запроса, отфильтрованные только по первому фильтру. var entities1 = esqCities.GetEntityCollection(UserConnection);
Пример 2
Пример демонстрирует как из корневой схемы [ActivityCategory] по обратным связям выбрать результаты активностей для конкретной категории.
// Создание экземпляра запроса с корневой схемой ActivityCategoryResultEntry. var esqResult = new EntitySchemaQuery(UserConnection.EntitySchemaManager, "ActivityCategoryResultEntry"); // Добавление в запрос колонки с результатом активности. esqResult.AddColumn("ActivityResult"); // Определение идентификатора активности, для которой будут выбираться результаты. var requiredActivityCategoryId = new Guid("42C74C49-58E6-DF11-971B-001D60E938C6"); // Создание экземпляра фильтра для выбора результатов для конкретной категории активности. var filter = esqResult.CreateFilterWithParameters(FilterComparisonType.Equal, "ActivityCategory.Id", requiredActivityCategoryId); // Добавление фильтра в коллекцию фильтров запроса. esqResult.Filters.Add(filter); // Текст результирующего sql-запроса (MS SQL): // SELECT // [ActivityCategoryResultEntry].[ActivityResultId] [ActivityResultId], // [ActivityResult].[Name] [ActivityResult.Name] // FROM // [dbo].[ActivityCategoryResultEntry] [ActivityCategoryResultEntry] // LEFT OUTER JOIN [dbo].[ActivityResult] [ActivityResult] // ON ([ActivityResult].[Id] = [ActivityCategoryResultEntry].[ActivityResultId]) // WHERE // EXISTS ( // SELECT // [ActivityCategory].[Id] [Id] // FROM // [dbo].[ActivityCategory] [ActivityCategory] // WHERE // [ActivityCategoryResultEntry].[ActivityCategoryId] = [ActivityCategory].[Id] // AND [ActivityCategory].[Id] = '{42C74C49-58E6-DF11-971B-001D60E938C6}')