Dynamics365FO. Невозможность синхронизации Data Entity, которая использует поле TableId в связях.

Category: Статьи Post Date: 25.05.2020

Некоторые таблицы используют поля RefRecId и RefTableId для связки с другими таблицами. Следовательно, создание Data Entity для этих таблиц может быть не таким простым делом. Давайте возьмем для примера таблицу WHSFilterTable. Мы хотим создать новую Data Entity для работы с кодами фильтров клиентов. Существует стандартная Data Entity, но мы создадим новую, чтобы продемонстрировать данную проблему. В нашей сущности мы присоединим к таблице WHSFilterTable таблицу CustTable. Связка между таблицами:

Запрос Data Entity будет такого вида:

Объект успешно компилируется , но во время синхронизации БД мы получаем огромный список ошибок. Я не буду перечислять весь список. Но основной из них является «System.Data.SqlClient.SqlException (0x80131904): Invalid column nameTABLEID’.», которая возникает в момент создания триггера. Механизм синхронизации создает оператор SQL, в котором используется поле TableId, но оно не является реальным полем и не существует в соответствующих таблицах SQL.

Так что же нам делать? Поскольку нам нужна данная Data Entity, и довольно часто в связках используется поле RefTableId, поэтому ошибка не является специфичной только для таблицы WHSFilterTable.

Пропустить создание триггеров

Если вы посмотрите на представление SQL, сгенерированные для Data Entity, вы можете заметить, что довольно многие из них вообще не имеют триггеров. Триггеры создаются только для Data Entity, которые поддерживают массовые операции, измените значение свойства «Enable Set Based SQL Operations» на «No», тогда триггеры не будут создаваться, и сущность будет синхронизирована без проблем.

Не использовать поле TableId в связке

Вместо того, чтобы иметь связку по полю TableId, мы можем удалить её из узла связей источников данных нашей сущности и добавить фильтр по полю RefTableId. Значением для этого фильтра может быть метод класса SysQueryRangeUtil, который просто возвращает значение tableNum(CustTable). Значение вычисляется только один раз во время синхронизации БД, а затем внедряется в определение представления. И это как раз тот вариант решения, который вы можете увидеть в стандартной Data Entity WHSCustomerProductFilterEntity. Он использует метод WHSCustomerProductFilterEntityHelper::getCustomers() для решения этой конкретной проблемы в стандарте.

Флайтинг (flighting)

Вы можете использовать специальную настройку DbSyncEnableTableIdInDataEntityTriggerRelations:

INSERT INTO SYSFLIGHTING (FLIGHTNAME, ENABLED, FLIGHTSERVICEID) VALUES (‘DbSyncEnableTableIdInDataEntityTriggerRelations’, 1, 12719367))

Это вынудит механизм синхронизации использовать фактические значения идентификаторов таблиц вместо ссылок на поле TableId на этапе генерации триггеров, и это выглядит будто данная настройка была введена как раз для решения этой проблемы. Я понятия не имею, почему это нигде не задокументировано и не включено по умолчанию.

Ссылку на оригинал можно найти здесь.

Подписывайтесь на канал @d365neti в Telegram

Подписаться

Добавить комментарий