Выборки

Для осуществления выборок из ссылочных коллекций реализован класс "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);