AXForum  
Вернуться   AXForum > Microsoft Dynamics AX > DAX: Программирование
All
Забыли пароль?
Зарегистрироваться Правила Справка Пользователи Сообщения за день Поиск

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 11.01.2012, 23:13   #1  
sukhanchik is offline
sukhanchik
Administrator
Аватар для sukhanchik
MCBMSS
Злыдни
Лучший по профессии 2015
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
3,311 / 3547 (125) ++++++++++
Регистрация: 13.06.2004
Адрес: Москва
AX 2012 Наследование таблиц. Краткое описание механизма
Добрый день! Пришлось тут в рамках подготовки к курсу 80299 What's New -Technical in Microsoft Dynamics AX 2012 for Development поисследовать AX 2012, и, поискав достаточно скудную информацию о наследовании таблиц (на русском – так вообще отсутствующую) – решил поисследовать самостоятельно – что же это за технология изнутри. Описанное ниже является исключительно моим мнением, не претендующим на истину в последней инстанции, и не являющееся заменой документации по данной функциональности.
Предназначение

Данная технология хорошо предназначена для разделения одной большой таблицы по полям на несколько маленьких (подразумевается вертикальное разделение – когда часть полей из большой таблицы «уезжает» в другую). Хорошим примером ситуации, когда наследование таблиц имеет смысл применять – являются таблицы InventJournalTrans / LedgerJournalTrans – строки журналов, в которых имеются поля, специфичные только для журналов определенного типа, а для остальных данных – они являются ненужными. Примером здесь могут являться поля, относящиеся к основным средствам (для LedgerJournalTrans) или поля, относящиеся к инвентаризации (для InventJournalTrans).
Принцип построения структуры таблиц в СУБД

Наследование таблиц, как технология – реализована в АХ 2012 по принципу абстрагирования программиста от СУБД (как в 1С), когда разработчик задает системе некоторые принципы, а ядро реализует эти принципы в СУБД и при исполнении кода. На самом деле – эта идеология (с т.з. структуры СУБД) уже была применена в АХ 2009 в таблицах InventJournalTrans и InventJournalTrans_Tag, а также в LedgerJournalTrans и LedgerJournalTrans_Asset, LedgerJournalTrans_Project, LedgerJournalTrans_RCash, LedgerJournalTrans_RAsset, LedgerJournalTrans_RDeferrals. Все эти таблицы связаны друг с другом отношением 1:0 или 1:1 (т.е. к примеру – в таблице LedgerJournalTrans_Asset может присутствовать только одна запись для одной записи в LedgerJournalTrans или же полностью отсутствовать, если запись в LedgerJournalTrans не имеет отношения к международным Осам). Связка осуществляется по RecId. Из этого списка несколько выпадают таблицы LedgerJournalTrans_RDeferrals (здесь в одной записи – ссылки на две разных записи в LedgerJornalTrans) и InventJournalTrans_Tag (здесь связь осуществляется по JournalId + LineNum, а не RecId). Кстати говоря, эти таблицы так и остались в АХ 2012 без иерархии (т.е. не состоящие в иерархии).
Таким образом, всю цепочку таблиц, участвующих в иерархии можно взять и заменить одной большой мегатаблицей, в полях которых будет много пустых данных. Поля в этой одной большой мегатаблице будут состоять из всех полей всех таблиц, участвующих в иерархии (за исключением, безусловно системных полей).
Состав функционала иерархии таблиц

В АХ 2012 под иерархией (наследованием) таблиц (Table Hierarchy, Table Inheritance) подразумевается:
· Функционал ядра, позволяющий строить структуру таблиц, описанную выше, связи между которыми будут осуществляться по RecId родительской таблицы (в нашем примере иерархия двухуровневая и родительскими таблицами являются это LedgerJournalTrans / InventJournalTrans). Важно! RecId производной таблицы совпадает с RecId базовой, т.о. в производной таблице может быть не более одной записи, соответствующей записи в базовой (родительской) таблице.
· Функционал наследования методов у производной таблицы (Derived Table) от ее родительской / базовой (Base Table)
· Функционал автоматического добавления всех базовых и производных таблиц на форму, при добавлении таблицы из иерархии на форму
· Функционал выбора производной таблицы на форме при создании записи (в таблицах, которые являются базовыми к добавляемой – запись создается автоматически при создании записи в таблице, прописанной в датасорсе. Задача разработчика – обеспечить возможность заполнения всех обязательных полей во всех таблицах иерархии при создании записи – иначе запись сохранена не будет).
· Механизм настройки иерархии таблиц в АОТ.
Запрос, генерирующийся к СУБД на форме

Запрос, генерирующийся к СУБД на форме содержит в себе все таблицы из иерархии – как производные, так и базовые (т.к. везде нужно добавлять одно и тоже значение RecId). Т.о. крупная иерархия (состоящая из большого количества таблиц) может привести к большому количеству джойнов, причем связи между таблицами осуществляются по LEFT OUTER JOIN, что не добавляет скорости к выборке (по сравнению с INNER JOIN). Поддержка сортировки и фильтрации таблиц, связанных по LEFT OUTER JOIN на форме появилась в AX 2012, поэтому эти данные можно на форме фильтровать / сортировать, как будто это одна большая мегатаблица.
«Академическим» примером наследования таблиц является глобальная адресная книга (DirPartyTable).
Название: DirPartyTableHierarhy.PNG
Просмотров: 6363

Размер: 7.1 Кб
Посмотрим, как это все будет выглядеть на форме. Для этого создадим простейшую форму, в которую добавим датасорс DirPartyTable
Название: DirPartyFormAOT.PNG
Просмотров: 5113

Размер: 25.2 Кб
И добавим грид с полями из разных таблиц:
DirPartyTable.Name
DirPerson.BirthMonth
DirPerson.BirthYear
DirPerson.BirthDay
DirOrganizationBase.PhoneticName
Название: DirPartyFormShow.PNG
Просмотров: 5110

Размер: 19.1 Кб
Поля, помеченные кружочком являются unretrieved, т.е. невыбираемыми (проще говоря, из-за LEFT JOIN там стоит значение NULL, т.к. запись в соответствующей таблице отсутствует). Пустые значения (без кружочка) означают наличие записи в соответствующей таблице и незаполненное поле. На скриншоте видно, что, например, для записи «Coho Receivers» в DirPartyTable отсутствует запись в таблице DirPerson, но присутствует запись в таблице DirOrganizationBase с пустым значением поля PhoneticName.
Запрос, отправляемый к СУБД в этом случае выглядит так:
Нажмите на изображение для увеличения
Название: DirPartyQueryDesign.PNG
Просмотров: 695
Размер:	49.0 Кб
ID:	7453
В виде T-SQL:
Нажмите на изображение для увеличения
Название: DirPartyQueryTSQL.PNG
Просмотров: 693
Размер:	58.9 Кб
ID:	7454
Если же мы вдруг решили добавить на форму таблицу из середины иерархии, к примеру OmInternalOrganization, то запрос к СУБД в этом случае будет выглядеть так:
Нажмите на изображение для увеличения
Название: HalfDirPartyQueryDesign.PNG
Просмотров: 532
Размер:	32.3 Кб
ID:	7456

В виде T-SQL:
Нажмите на изображение для увеличения
Название: HalfDirPartyQueryTSQL.PNG
Просмотров: 629
Размер:	11.4 Кб
ID:	7457
В этом примере наглядно видно, как из запроса исчезла таблица DirPerson, т.к. она не является ни базовой ни производной к таблице OmInternalOrganization. Также обращаю внимание на появление CROSS JOIN-ов к базовым таблицам.
Вопрос осмысленности добавления таблицы из середины иерархии я оставляю в стороне, т.к. цель данной статьи – показать, как это будет работать в различных вариантах исполнения. А понимание бизнес-применения наследования таблиц придет со временем.
Процедура создания иерархии таблиц

1. Создать обе таблицы (базовую и производную), как элементы в АОТ без дополнительных полей.
2. Создать в базовой таблице поле типа Int64, наследованное от типа \System Documentation\Types\RelationType и назвать его InstanceRelationType (должно быть точно такое название). В этом поле будет храниться код производной таблицы (TableId).
3. На базовой таблице включить свойство SupportInheritance = Yes и выбрать в свойстве InstanceRelationType одноименное только что созданное поле. Сохранить базовую таблицу.
Нажмите на изображение для увеличения
Название: BaseTableProperties.PNG
Просмотров: 581
Размер:	24.3 Кб
ID:	7448
4. На производной таблице включить свойство SupportInheritance = Yes и выбрать в свойстве Extends базовую таблицу. Автоматически создастся Relation на базовую таблицу. Сохранить производную таблицу.
Нажмите на изображение для увеличения
Название: DerivedTableProperties.PNG
Просмотров: 631
Размер:	23.9 Кб
ID:	7449
Свойства созданного Relation:
Нажмите на изображение для увеличения
Название: DerivedTableRelation.PNG
Просмотров: 543
Размер:	24.8 Кб
ID:	7450
5. Добавить остальные необходимые поля в базовую и производную таблицу.
Версия системы

Данная статья подготовлена по версии АХ 2012:
Kernel version: 6.0.947.0
Application version: 6.0.947.0

Обсуждение на форуме ранее

axdaily: Table inheritance
Наследование таблиц в 2012, кто нибудь уже использовал ?


Обновление для версии R2 и R3

В AX2012 R2 механизм наследования таблиц немного изменили.
На уровне АОТ механизм остался таким же как и был, а вот на уровне СУБД - теперь вся цепочка таблиц представляет собой одну большую базовую табличку, в которой собраны все поля из производных таблиц. Т.о. в вышеописанном примере все поля из таблички DirPerson и DirOrganizationBase "переехали" в DirPartyTable. А сами таблички исчезли из общего списка таблиц (их нет в БД; в т.ч. их описания нет в SQLDictionary).
В частности, теперь не стало таблички CompanyInfo, т.к. она также наследуется от DirPartyTable и, как следствие, все поля из этой таблички были перенесены в DirPartyTable.
Соответственно, все запросы (в т.ч. обновления данных) к БД упростились, т.к. теперь выборка осуществляется из одной таблицы, в случае подцепления любой таблицы из иерархии в датасорс формы.
Разница в выборке из производной таблицы и из базовой теперь лишь состоит в количестве полей, перечисленных в конструкции SELECT (при выборке в Х++ из производной таблицы - запрос к БД посылается к базовой таблице, но только по тем полям, которые перечислены в АОТе в производной таблице). Правда, выборка из производной таблицы дополнительно фильтруется по тем записям, которые относятся только к ней.
Т.е. запрос в Х++
X++:
select dirPerson
теперь уйдет в БД, как:
Нажмите на изображение для увеличения
Название: DirPerson.png
Просмотров: 663
Размер:	19.7 Кб
ID:	8097
Обращаю внимание на дополнительный фильтр по полю InstanceRelationType - он обеспечивает отбор только тех записей, которые должны относиться к DirPerson
А запрос в Х++
X++:
select dirPartyTable
теперь уйдет в БД, как:
Нажмите на изображение для увеличения
Название: DirPartyTable.png
Просмотров: 612
Размер:	34.1 Кб
ID:	8098
Данная информация справедлива для версии R2 CU1 (Ядро и приложение - 6.2.1000.156)
В версии R3 (Ядро и приложение - 6.3.164.0) никаких изменений по отношению к R2 по части данной статьи не произошло
__________________
Возможно сделать все. Вопрос времени

Последний раз редактировалось sukhanchik; 01.06.2014 в 13:59.
За это сообщение автора поблагодарили: mazzy (5), AlGol (2), macklakov (9), Berty Wooster (1), BOAL (9), AK-76 (1), Владимир Максимов (5), db (10), Pustik (5), Logger (10), lev (13), TasmanianDevil (7), ziva (2), AvrDen (1), oip (5), ivas (2), Stitch_MS (3), IvanS (1), Aquarius (1), alex55 (1), S.Kuskov (15), -Dmitry- (0), jeky (2), McArrow (1), Evgeniy_R (1).
Теги
ax2012, inheritance, table inheritance, наследование таблиц, полезное

 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
emeadaxsupport: New Content for Microsoft Dynamics AX 2012 : October 2011 Blog bot DAX Blogs 0 27.10.2011 17:11
dynamics-ax: Interview with Microsoft's Lachlan Cash on his new role, AX 2012 and more Blog bot DAX Blogs 6 22.04.2011 14:55
axinthefield: Dynamics AX Event IDs Blog bot DAX Blogs 0 01.03.2011 22:11
daxdilip: Whats New in Dynamics AX 2012 (A brief extract from the recently held Tech Conf.) Blog bot DAX Blogs 7 31.01.2011 12:35
dynamics-ax: Modeling the world, with Microsoft Dynamics AX 2012 Blog bot DAX Blogs 0 25.01.2011 09:11

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход

Рейтинг@Mail.ru
Часовой пояс GMT +3, время: 13:37.