Выборки
Для осуществления выборок из ссылочных коллекций реализован класс "ITworks.Brom.Селектор". Селектор позволяет:
- формировать выборки из ссылочных коллекций с учетом сложных отборов, в том числе по полям на неограниченной глубине и по полям табличных частей;
- формировать выборки с учетом сортировок по полям на неограниченной глубине;
- формировать выборки, содержащие контекстные данные самих объектов, а также объктов, на которые ссылаются внутренние поля.
Создать селектор можно:
- вызвав метод "СоздатьСелектор()" объекта "БромКлиент";
- вызвав метод "СоздатьСелектор()" модуля менеджера соответствующей коллекции.
Формирование выборки происходит:
- при вызове метода "Выполнить()" селектора;
- при получении инумератора селектора "GetEnumerator()".
Селектор может формировать выборки для следующих коллекций:
- Справочники;
- Документы;
- Перечисления;
- Планы видов характеристик;
- Планы счетов;
- Планы видов расчета;
- Бизнес-процессы;
- Задачи.
// Выборка всех элементов справочника "Номенклатура"
Селектор текСелектор = клиент.СоздатьСелектор();
текСелектор.УстановитьКоллекцию("Справочник.Номенклатура");
текСелектор.АвтозагрузкаПолей = АвтозагрузкаПолейОбъектов.ТолькоСтандартныеРеквизиты;
foreach (dynamic текСсылка in текСелектор) {
Console.WriteLine("Наименование: {0}; Код: {1}", текСсылка.Наименование, текСсылка.Код);
}
// Добавляем отбор и дозапрашиваем данные производителя
текСелектор.ДобавитьОтбор("ЭтоГруппа", false);
текСелектор.ДобавитьСортировку("Наименование");
текСелектор.ДобавитьПоля("Производитель, Производитель.ИНН");
foreach (dynamic текСсылка in текСелектор) {
Console.WriteLine("Наименование: {0}; Код: {1}, Производитель: {2}; ИНН: {3}",
текСсылка.Наименование,
текСсылка.Код,
текСсылка.Производитель,
текСсылка.Производитель.ИНН
);
}
// Сохраняем результат выборки в массив для последующего использования
Ссылка[] результат = текСелектор.ВыгрузитьРезультат();
// Выборка из справочника "Номенклатура" в стиле языка запросов
Селектор текСелектор = клиент.СоздатьСелектор();
текСелектор.
Выбрать("Наименование, Код, Производитель, Производитель.ИНН").
Первые(20).
Из("Справочник.Номенклатура").
Где("ЭтоГруппа", false).
Где("Родитель.Наименование", "Мебель").
Упорядочить("Наименование");
foreach (dynamic текСсылка in текСелектор) {
Console.WriteLine("Наименование: {0}; Код: {1}, Производитель: {2}; ИНН: {3}",
текСсылка.Наименование,
текСсылка.Код,
текСсылка.Производитель,
текСсылка.Производитель.ИНН
);
}
// Сохраняем результат выборки в массив для последующего использования
Ссылка[] результат = текСелектор.ВыгрузитьРезультат();
// Выборка номенклатуры из группы "Мебель"
dynamic группаМебель = клиент.Справочники.Номенклатура.НайтиПоНаименованию("Мебель");
Селектор текСелектор = клиент.Справочники.Номенклатура.СоздатьСелектор();
текСелектор.
Выбрать("Наименование, Код, Производитель, Производитель.ИНН").
Где("ЭтоГруппа", false).
Где("Ссылка", группаМебель, ВидСравнения.ВИерархии).
Упорядочить("Производитель").
Упорядочить("Наименование", НаправлениеСортирвки.Убывание);
foreach (dynamic текСсылка in текСелектор) {
Console.WriteLine("Наименование: {0}; Код: {1}, Производитель: {2}; ИНН: {3}",
текСсылка.Наименование,
текСсылка.Код,
текСсылка.Производитель,
текСсылка.Производитель.ИНН
);
}
// Сохраняем результат выборки в массив для последующего использования
Ссылка[] результат = текСелектор.ВыгрузитьРезультат();
// Выборка заказов с определенной даты, в которых есть товары из раздела "Мебель"
dynamic группаМебель = клиент.Справочники.Номенклатура.НайтиПоНаименованию("Мебель");
Селектор текСелектор = клиент.Документы.ЗаказКлиента.СоздатьСелектор();
текСелектор.
Выбрать("Дата, Номер, Контрагент").
Где("Проведен", true).
Где("Дата", new DateTime(2019, 1, 1), ВидСравнения.БольшеИлиРавно).
Где("Товары.Номенклатура", группаМебель, ВидСравнения.ВИерархии).
Упорядочить("Контрагент").
Упорядочить("Дата", НаправлениеСортирвки.Убывание);
foreach (dynamic текСсылка in текСелектор) {
Console.WriteLine("Дата: {0}; Номер: {1}; Контрагент: {2}",
текСсылка.Дата,
текСсылка.Номер,
текСсылка.Контрагент
);
}
// Сохраняем результат выборки в массив для последующего использования
Ссылка[] результат = текСелектор.ВыгрузитьРезультат();
Установка отборов
Установить отбор селектора можно:
- вызвав метод "ДобавитьОтбор()" селектора;
- вызвав метод "Где()" селектора (метод является синонимом).
В качестве параметров метода необходимо указать:
- Ключ поля (путь к данным поля), например "Ссылка", "Артикул", "Производитель.ИНН", "Родитель.Наименование". Допускается указывать путь к данным реквизитов табличных частей, например "Товары.Количество", "ДополнительныеРеквизиты.Свойство.Наименование" и тд...
- Значене сравнения сериализуемого типа. Тип значения должен соответствовать реквизиту;
- Вид сравнения (опционально, по умолчанию "Равно"). Вид сравнения может быть:
- Равно;
- НеРавно;
- Больше;
- БольшеИлиРавно;
- Меньше;
- МеньшеИлиРавно;
- Содержит;
- НеСодержит;
- ВСписке;
- НеВСписке;
- ВИерархии;
- НеВИерархии.
Для видов сравнения "ВСписке" и "НеВСписке" в качестве значения необходимо передавать массив значений (коллекцию, реализующую IList). Для видов сравнения "ВИерархии" и "НеВИерархии" можно передавать как одно значение (ссылку), так и массив значений (массив ссылок).
// Пример отборов для справочника
текСелектор.ДобавитьОтбор("Артикул", "Т-0001");
текСелектор.ДобавитьОтбор("Вес", 15, ВидСравнения.БольшеИлиРавно);
текСелектор.ДобавитьОтбор("Ссылка", группаМебель, ВидСравнения.НеВИерархии);
текСелектор.ДобавитьОтбор(
"Производитель.Родитель",
new Ссылка[] { ссылка1, ссылка2, ссылка3 },
ВидСравнения.ВСписке
);
// Пример отборов для документа
текСелектор.
Где("Дата", new DateTime(2019, 1, 1), ВидСравнения.БольшеИлиРавно).
Где("Товары.Номенклатура", new Ссылка[] { ссылка1, ссылка2, ссылка3 }, ВидСравнения.ВСписке).
Где("Проведен", true, ВидСравнения.Равно).
Где("ДокументОснование", клиент.Документы.ЗаказКлиента.ПустаяСсылка(), ВидСравнения.НеРавно);
Сортировка выборок
Указать сортировку выборки можно:
- вызвав метод "ДобавитьСортировку()" селектора;
- вызвав метод "Упорядочить()" селектора (метод является синонимом).
В качестве параметров метода необходимо указать:
- Ключ поля (путь к данным поля), например "Наименование", "Артикул", "Производитель.Код", "Родитель.Наименование" и тд..;
- Направление сортировки (опционально, по умолчанию "Возрастание").
текСелектор.ДобавитьСортировку("Наименование");
текСелектор.ДобавитьСортировку("Производитель.Наименование", НаправлениеСортирвки.Убывание);
текСелектор.
Упорядочить("Дата", НаправлениеСортирвки.Убывание).
Упорядочить("Контрагент");
Загрузка контекстных данных
Сам по себе селектор является коллекцией ссылок, реализующей интерфейс "IEnumerable". В некоторых случаях возникает необходимость получения доступа к контекстным данным объектов (к данным реквизитов и табличных частей), на которые эти ссылки указывают. Доступ к данным может быть получен путем обращения к динамическим полям ссылки, например "текСсылка.Артикул", однако при таком обращении будет отправлен запрос серверу с последующей загрузкой полного набора контекстных данных. Чтобы избежать множественных запросов к серверу и избыточной загрузки данных, в классе селектора предусмотрена возможность указания полей объекта, которые должны быть загружены единовременно вместе с формированием выборки.
Указать дополнительные поля выборки можно:
- вызвав метод "ДобавитьПоля()" селектора;
- вызвав метод "Выбрать()" селектора (метод является синонимом).
В качестве параметров метода необходимо указать список полей, данные которых необходимо загрузить. Могут быть указаны как поля самого объекта выборки, так и подчиненные поля, например "Производитель.Родитель.Наименование", "Контрагент.ИНН" и тд...
// Неоптимальный вариант работы с данными
Селектор текСелектор = клиент.Справочники.Номенклатура.СоздатьСелектор();
foreach (dynamic текСсылка in текСелектор) {
Console.WriteLine("Наименование: {0}; Производитель: {1}", текСсылка.Наименование, текСсылка.Производитель);
// В каждой итерации будет происходить два запроса на сервер:
// - запрос на получение ВСЕХ контекстных данных ссылки "текСсылка", включая данные табличных частей;
// - запрос на получение ВСЕХ контекстных данных ссылки "Производитель" для формирования представления ссылки.
// Это медленно и крайне неэффективно!
}
// Оптимальный вариант работы с данными
Селектор текСелектор = клиент.Справочники.Номенклатура.СоздатьСелектор();
текСелектор.ДобавитьПоля("Наименование, Производитель");
foreach (dynamic текСсылка in текСелектор) {
Console.WriteLine("Наименование: {0}; Производитель: {1}", текСсылка.Наименование, текСсылка.Производитель);
// Дополнительных запросов на сервер происходить не будет,
// т.к. необходимые данные уже загружены с сервера и помещены в контекст
}
Селектор текСелектор = клиент.Справочники.Номенклатура.СоздатьСелектор();
// Запрашиваем данные, которые понадобятся для дальнейшей работы
текСелектор.
Выбрать("Наименование, Родитель.Код, Производитель.Родитель.Наименование").
Выбрать("ПометкаУдаления, ДополнительныеРеквизиты");
foreach (dynamic текСсылка in текСелектор) {
// TODO
}
В классе селектора также предусмотрено свойство "АвтозагрузкаПолей", которое позволяет указать, какие именно данные необходимо загружать вместе с выборкой, без указания конкретных имен полей.
// Будут загружены данные только стандартных реквизитов
текСелектор.АвтозагрузкаПолей = АвтозагрузкаПолейОбъектов.ТолькоСтандартныеРеквизиты;
// Будут загружены данные всех реквизитов объекта (без табличных частей)
текСелектор.АвтозагрузкаПолей = АвтозагрузкаПолейОбъектов.ТолькоРеквизиты;
// Будут загружены все данные объекта (реквизиты и табличные части)
текСелектор.АвтозагрузкаПолей = АвтозагрузкаПолейОбъектов.ВсеПоля;
Подробная информация по работе со ссылками и контекстными данными ссылок представлена в разделе "Работа со ссылками".
Ограничение размера выборки
Ограничить количество выбираемых элементов можно:
- установив свойство "Лимит";
- вызвав метод "Первые()".
текСелектор.Лимит = 10;
текСелектор.Первые(10);