Интеграционные dll, которые входят в состав Аксапты 2012, могут перестать работать, если нужные им объекты перенесены в другой слой.

Данный метод работает только с открытыми объектами в базе данных моделей AX2012 и использует штатные SQL-инструменты.
В данном методе не используются недокументированные возможности.

Используйте советы из данной статьи только в тестовом окружении для изучения Аксапты. Не используйте эти советы на ПРОДе и/или если вы планируете ставить обновления от Microsoft.

Основная идея данного метода – заставить SQL-сервер выполнить каскадное обновление поля LayerId во всех связанных таблицах базы данных модели AX2012. Поэтому, последовательность шагов:

  1. Удалить элементы, для которых есть покрывающий элемент в слое выше
  2. Установить Cascade Update для таблиц, в которых есть ModelId+LayerId в базе данных модели
  3. Выполнить update поля LayerId в таблице Model (SQL выполнит каскадное обновление LayerId в остальных таблицах)
  4. Пост-обработка

Удалить элементы, для которых есть покрывающий элемент в слое выше

Каждый элемент бизнес-логики может быть представлен в нескольких слоях. Но при этом работает только элемент самого верхнего слоя. Кроме того, среда разработки гарантирует, что элементы в разных слоях содержат непротиворечивые данные, если в результате глобальной компиляции бизнес-логики отсутствуют ошибки компиляции.

Остановите AOS и выполните SQL-команду, которая удаляет определение элементов из нижних слоев (ближе к sys), если есть определение этого элемента в слое выше (ближе к usr).

delete from [ModelElementData]
where LayerId < 14                                      -- USR layer
  and exists (
    select top 1 * from [ModelElements]                 -- view ModelElement+ModelElementData 
    where [ModelElements].ElementType not in (117, 118) -- Label and Label files
      and [ModelElements].ElementHandle = [ModelElementData].ElementHandle
      and [ModelElements].LayerId > [ModelElementData].LayerId
  );

На скриншоте ниже показано, как выглядит таблица LedgerJournalTmp в AOT. Каждый узел дерева – это элемент в таблице ModelElement в базе данных моделей AX2012.

Элемент AOT, размещенный в нескольких слоях

После выполнения этой SQL-команды в базе данных моделей для каждого элемента останется только одно определение в самом верхнем слое.

Элемент AOT, размещенный в одном слое

Установить Cascade Update для таблиц, в которых есть ModelId+LayerId в базе данных модели

В SQL management studio пройдитесь по всем таблицам базы данных моделей AX2012. Установите Cascase у правила обновления для каждой таблицы, у которой есть FK по полю LayerId и уже установлено каскадное удаление.

А для FK_ModelElementData_HasModelId_LayerId в таблице ModelElementData надо изменить и правило для удаления, и правило для обновления: установите Cascade.

set Update Rule = Cascade

Примечание 1: Список полей в relation можно посмотреть в диалоге Foreign Key Relations в строке Tables and Columns Specification.

Примечание 2: SSRS отображает одно и то же отношение для обеих таблиц, которые участвуют в Relation. Поэтому изменив правило Update Rule для одной таблицы, вы можете обнаружить, что в другой таблице это правило уже изменено.

Примечание 3: Возможно, кто-то захочет создать скрипт для автоматизации этой настройки. Однако, в разных релизах эти связи чуть-чуть отличаются. Поэтому мне было проще пройтись руками и лично удостоверится, что Update Rule установлены правильно, нежели писать и отлаживать универсальный скрипт.

Все доступные программисту объекты АОТ находятся в usr-слое

Выполнить update поля LayerId в таблице Model

Выполните SQL-команду, чтобы перенести все объекты в usr-слой

update [Model]
set LayerId = 14	-- USR layer
where id >= 17		-- Foundation model
  and LayerId <> 14

Рекомендуется увеличить размер Transaction log перед выполнением этой команды. Не жалейте, поставьте размер вдвое больше, чем размер самой базы данных моделей.

После запуска AOS все доступные программисту объекты АОТ находятся в usr-слое.

Пост-обработка

После массовых обновлений рекомендуется выполнить обслуживание базы данных моделей на SQL-сервере: перестроить индексы и статистику.

Также в самой Аксапте стоит выполнить поиск по перекрестным ссылкам, найти и исправить X++ код, который явно определяет слой. Например, ApplicationVersion::applBuildNo().