Тип entity
Общие сведения
Ссылочные типы данных 1С:Предприятие 8 - это сущности, которые идентифицируются своим уникальным ключом (ссылкой), а не значениями своих свойств. При помощи такого ключа можно ссылаться на отдельно взятые сущности в свойствах других объектов. На уровне реляционной базы данных ссылки играют роль первичных и внешних ключей. Например, ссылочными типами данных являются справочники и документы 1С:Предприятие 8.
Тип данных entity
- это ссылка. Внутренняя реализация entity
представляет собой структуру, которая состоит из двух полей: целочисленный код типа ссылки (integer) и уникальный идентификатор (UUID). Данная структура является указателем (ссылкой) на конкретный объект в базе данных или его отсутствие - “пустая ссылка”.
Интересно отметить, что с точки зрения, например ORM (object-relational mapping), код типа ссылки играет роль дискриминатора типа и используется на уровне прикладного кода и таблиц базы данных соответствующим образом.
“Пустая ссылка” всегда строго типизированна, то есть указывает на отсутствие объекта какого-то определённого типа, например, “Справочник.Номенклатура”.
Специальным значением
entity
является “нулевая ссылка” (значение по умолчанию). Это ссылка, которая ни на что не указывает, так как ей пока что не присвоено конкретное значение.
Структура хранения ссылок на уровне СУБД
Поле СУБД | MS SQL Server | PostgreSQL | C# | DaJet Script | Примечание |
---|---|---|---|---|---|
_TRef | binary(4) | bytea | int | number | Код типа ссылкиВ определённых случаях может отсутствовать для оптимизации (уменьшения) объёма хранимых данных |
_RRef | binary(16) | bytea | Guid | uuid | Значение ссылкиОбязательное поле |
Представление различных видов ссылок entity
Нулевая ссылка: {0:00000000-0000-0000-0000-000000000000}
Пустая ссылка: {36:00000000-0000-0000-0000-000000000000}
Конкретная ссылка: {36:08ec109d-a06b-a1b1-11ee-ca472bff0a0d}
Целочисленный код типа ссылки определяется и фиксируется в момент создания нового класса сущности в информационной базе 1С:Предприятие 8. В терминах 1С это называется “объект метаданных”. Например, объект метаданных справочника “Номенклатура” может иметь код 12
в одной информационной базе 1С:Предприятие 8, однако, в другой информационной базе одноимённый и аналогичный по содержанию справочник может иметь другое значение кода своего типа, например, 21
.
Другими словами, код типа объекта метаданных зависит от контекста базы данных, в которой он был создан.
Важно отметить, что код типа метаданного используется для формирования имён прикладных таблиц базы данных, где хранятся пользовательские данные приложения 1С:Предприятие 8. Например, если код справочника “Номенклатура” имеет значение
36
, то имя его таблицы будет равно_Reference36
.
Кроме этого, на уровне хранилища метаданных 1С:Предприятие 8 существует внутренний уникальный идентификатор типа объекта метаданных в виде UUID. Этот идентификатор также генерируется в момент создания нового объекта метаданных. Однако, он имеет исключительно служебное значение и не используется для хранения в прикладных таблицах приложения 1С:Предприятие 8.
Таким образом, в целях синхронизации данных приложений идентичных или аналогичных объектов метаданных между различными информационными базами 1С:Предприятие 8 используются их строковые представления или “полное имя объекта метаданных”, например, “Справочник.Номенклатура”.
Уникальный идентификатор ссылки генерируется платформой 1С:Предприятие 8 или присваивается разработчиком прикладного решения в момент создания новой сущности определённого типа и её записи в базу данных. Эта возможность часто используется для синхронизации сущностей “по ссылке” при обменах данными между различными прикладными решениями. Например, типовые решения 1С:Предприятие 8 для этих целей используют таблицы соответствия идентификаторов объектов между собой (регистр сведений “СоответствияОбъектовИнформационныхБаз”).
Значение типа entity
можно получить из базы данных 1С:Предприятие 8 при помощи следующего кода DaJet Script:
DECLARE @Ссылка entity
USE 'mssql://server/database'
SELECT TOP 1 Ссылка INTO @Ссылка
FROM Справочник.Номенклатура
WHERE Код = 'ABCD-1234'
END
PRINT @Ссылка
-- Результат выполнения скрипта
[2024-10-01 14:31:59] {36:08ec109d-a06b-a1b1-11ee-ca472bff0a0d}
Далее можно использовать полученную ссылку в запросах для фильтрации данных, например, следующим образом:
DECLARE @array array
DECLARE @object object
DECLARE @Ссылка entity
USE 'mssql://server/database'
-- Получаем ссылку на нужный товар
SET @Ссылка = SELECT TOP 1 Ссылка
FROM Справочник.Номенклатура
WHERE Код = 'ABCD-1234'
-- Выбираем дату, номер и сумму тех документов,
-- в которых клиенты заказывали нужный товар
SELECT DISTINCT
Дата = Документ.Дата
, Номер = Документ.Номер
, Сумма = Документ.СуммаДокумента
INTO @array
FROM Документ.ЗаказКлиента.Товары AS Товары
INNER JOIN Документ.ЗаказКлиента AS Документ
ON Документ.Ссылка = Товары.Ссылка
WHERE Товары.Номенклатура = @Ссылка
END
-- Выводим результат в лог программы
FOR @object IN @array
PRINT JSON(@object)
END
-- Результат выполнения скрипта
[2024-10-03 13:14:35] {"Дата":"2023-01-01T00:00:00","Номер":"00000001","Сумма":123.00}
[2024-10-03 13:14:35] {"Дата":"2023-06-24T02:07:24","Номер":"00000003","Сумма":333.00}
Функции для работы с типом entity
Для удобства работы с типом entity
в DaJet Script реализован набор встроенных функций. Эти функции позволяют создавать новые ссылки из простых типов number
и uuid
, получать значения полей структуры entity
и так далее. Некоторые функции имеют перегруженные версии, то есть отличаются набором параметров. Кроме этого функции отличаются между собой требованием наличия контеста СУБД, то есть вызовом “внутри” команды USE, а также возможностью использования в запросах СУБД или выражениях DaJet Script.
Таблица функций типа entity
Функция | Возврат | Параметры | Описание | Команда USE | Запрос СУБД | Выражение DaJet Script |
---|---|---|---|---|---|---|
ENTITY | entity | string | Создаёт пустую ссылку по полному имени объекта метаданных | да | нет | да |
ENTITY | entity | string uuid |
Создаёт конкретную ссылку по полному имени объекта метаданных и идентификаторуНаличие объекта в базе данных, имеющего такую ссылку, не гарантировано |
да | нет | да |
ENTITY | entity | number uuid |
Создаёт конкретную ссылку или пустую ссылку по коду типа объекта метаданных и идентификатору | нет | нет | да |
TYPEOF | number | string | Получает значение кода типа объекта метаданных по его полному имени | да | да | да |
TYPEOF | number | entity | Получает значение кода типа объекта метаданных из ссылки, структуры entity |
да | да | да |
TYPEOF | number | поле таблицы базы данных |
Получает значение кода типа объекта метаданных из поля таблицы базы данных, которое хранит значение ссылки, структуры entity |
да | да | нет |
UUIDOF | uuid | entity | Получает значение идентификатора объекта из ссылки, структуры entity |
да | да | да |
UUIDOF | uuid | поле таблицы базы данных |
Получает значение идентификатора объекта из поля таблицы базы данных, которое хранит значение ссылки, структуры entity |
да | да | нет |
NAMEOF | string | number | Получает полное имя объекта метаданных по его коду типа | да | нет | да |
NAMEOF | string | entity | Получает полное имя объекта метаданных из ссылки, структуры entity |
да | нет | да |
Функция ENTITY
DECLARE @name string = 'Справочник.Номенклатура'
DECLARE @type number = 36 -- Код типа Справочник.Номенклатура
DECLARE @uuid uuid = '08ec109d-a06b-a1b1-11ee-ca472bff0a0d'
DECLARE @empty uuid = '00000000-0000-0000-0000-000000000000'
DECLARE @object object
USE 'mssql://server/database'
SET @object = SELECT by_name_no_uuid = ENTITY(@name)
, by_name_zero_uuid = ENTITY(@name, @empty)
, by_name_and_uuid = ENTITY(@name, @uuid)
, by_type_and_uuid = ENTITY(@type, @uuid)
END
PRINT 'Пустая ссылка по имени объекта метаданных : ' + @object.by_name_no_uuid
PRINT 'Пустая ссылка по имени и нулевому UUID : ' + @object.by_name_zero_uuid
PRINT 'Конкретная ссылка по имени и UUID : ' + @object.by_name_and_uuid
PRINT 'Конкретная ссылка по коду типа и UUID : ' + @object.by_type_and_uuid
-- Результат выполнения скрипта
[2024-10-03 14:25:06] Пустая ссылка по имени объекта метаданных : {36:00000000-0000-0000-0000-000000000000}
[2024-10-03 14:25:06] Пустая ссылка по имени и нулевому UUID : {36:00000000-0000-0000-0000-000000000000}
[2024-10-03 14:25:06] Конкретная ссылка по имени и UUID : {36:08ec109d-a06b-a1b1-11ee-ca472bff0a0d}
[2024-10-03 14:25:06] Конкретная ссылка по коду типа и UUID : {36:08ec109d-a06b-a1b1-11ee-ca472bff0a0d}
Функция TYPEOF
DECLARE @Ссылка entity
DECLARE @name string = 'Справочник.Номенклатура'
DECLARE @type number
DECLARE @code number
DECLARE @empty uuid = '00000000-0000-0000-0000-000000000000'
USE 'pgsql://postgres:postgres@127.0.0.1:5432/database'
SET @type = TYPEOF(@name)
SET @Ссылка = ENTITY(@type, @empty)
SET @code = SELECT TOP 1 TYPEOF(Ссылка)
FROM Справочник.Номенклатура
END
PRINT 'Коды типа "Справочник.Номенклатура"'
PRINT 'TYPEOF(имя метаданного) = ' + @type
PRINT 'TYPEOF(ссылка на объект в коде) = ' + TYPEOF(@Ссылка)
PRINT 'TYPEOF(поле таблицы в запросе) = ' + @code
-- Результат выполнения скрипта
[2024-10-03 15:12:49] Коды типа "Справочник.Номенклатура"
[2024-10-03 15:12:49] TYPEOF(имя метаданного) = 38
[2024-10-03 15:12:49] TYPEOF(ссылка на объект в коде) = 38
[2024-10-03 15:12:49] TYPEOF(поле таблицы в запросе) = 38
Характерный пример использования функции TYPEOF
- фильтрация данных по их типу:
DECLARE @monitor object -- Результаты мониторинга
DECLARE @УзелИнтеграции entity -- Узел получения данных
DECLARE @ТипМетаданных string = 'Справочник.Номенклатура'
USE 'pgsql://postgres:postgres@127.0.0.1:5432/database'
SELECT Ссылка INTO @УзелИнтеграции
FROM ПланОбмена.ПланОбменаРИБ
WHERE Код = 'РИБ-0001'
SELECT КоличествоОбъектов = COUNT(*)
, ОбъёмДанныхБайт = SUM(DATALENGTH(Данные))
INTO @monitor
FROM РегистрСведений.РегистрацияИзменений
WHERE Узел = @УзелИнтеграции
AND Ссылка = TYPEOF(@ТипМетаданных)
END
PRINT 'Мониторинг исходящих данных'
PRINT '* ' + @ТипМетаданных + ' *'
PRINT '- Количество объектов = ' + @monitor.КоличествоОбъектов
PRINT '- Объём данных (байт) = ' + @monitor.ОбъёмДанныхБайт
-- Результат выполнения скрипта
[2024-10-03 16:18:04] Мониторинг исходящих данных
[2024-10-03 16:18:04] * Справочник.Номенклатура *
[2024-10-03 16:18:04] - Количество объектов = 4
[2024-10-03 16:18:04] - Объём данных (байт) = 68
Функция UUIDOF
DECLARE @Ссылка entity
DECLARE @uuid uuid
USE 'pgsql://postgres:postgres@127.0.0.1:5432/database'
SELECT TOP 1 Ссылка INTO @Ссылка
FROM Справочник.Номенклатура
SELECT TOP 1 UUIDOF(Ссылка) INTO @uuid
FROM Справочник.Номенклатура
END
PRINT 'Идентификаторы ссылки типа "Справочник.Номенклатура"'
PRINT 'UUIDOF(поле таблицы в запросе) = ' + @uuid
PRINT 'UUIDOF(ссылка на объект в коде) = ' + UUIDOF(@Ссылка)
-- Результат выполнения скрипта
[2024-10-03 15:30:09] Идентификаторы ссылки типа "Справочник.Номенклатура"
[2024-10-03 15:30:09] UUIDOF(поле таблицы в запросе) = 8d40f59c-935c-8ecc-11ee-23466f6fe660
[2024-10-03 15:30:09] UUIDOF(ссылка на объект в коде) = 8d40f59c-935c-8ecc-11ee-23466f6fe660
Функция NAMEOF
DECLARE @name string = 'Справочник.Номенклатура'
DECLARE @entity entity -- Ссылка на объект
DECLARE @type_code number -- Код типа объекта
DECLARE @from_code string
DECLARE @from_entity string
USE 'pgsql://postgres:postgres@127.0.0.1:5432/database'
SET @entity = ENTITY(@name) -- Создаём пустую ссылку по имени
SET @type_code = TYPEOF(@name) -- Получаем код типа по имени
SET @from_code = NAMEOF(@type_code) -- Имя типа по его коду
SET @from_entity = NAMEOF(@entity) -- Имя типа из ссылки
END
PRINT 'Получение полного имени типа объекта метаданных'
PRINT '- по коду типа = ' + @from_code
PRINT '- из ссылки на объект = ' + @from_entity
-- Результат выполнения скрипта
[2024-10-03 15:47:51] Получение полного имени типа объекта метаданных
[2024-10-03 15:47:51] - по коду типа = Справочник.Номенклатура
[2024-10-03 15:47:51] - из ссылки на объект = Справочник.Номенклатура
Типизированное объявление entity
Существует ещё один способ объявить переменную типа entity
. Этот способ позволяет указать тип ссылки при помощи строкового представления объекта метаданных 1С:Предприятие 8. Такое объявление делает код более наглядным. Важно отметить, что нижеследующий код будет работать корректно только “внутри” блока команды USE, так как разрешение имён метаданных и их кодов зависит от контекста соответствующей информационной базы 1С:Предприятие 8.
USE 'mssql://server/database'
DECLARE @Ссылка Справочник.Номенклатура
PRINT @Ссылка
END
-- Результат выполнения скрипта
[2024-10-01 14:46:58] {36:00000000-0000-0000-0000-000000000000}