08.12.2020, 19:39 | #1 |
Участник
|
D365FO: Navigation methods are not supported at this time?
Кто в курсе, NavigationPropertyMethod действительно не поддерживается в D365FO?
просто на этих методах основан Unit Of Work. И теперь получается, что Unit of Work тоже не поддерживается? см. также. https://community.dynamics.com/ax/b/...s/unit-of-work |
|
09.12.2020, 06:20 | #2 |
Участник
|
Почему не поддерживается. Поддерживается, то только без экстеншенов.
А кстати какая идея вообще стоит за UnitOfWork, почему нельзя просто присваивать связи в транзакции? |
|
|
За это сообщение автора поблагодарили: sukhanchik (6). |
09.12.2020, 11:04 | #3 |
Administrator
|
Цитата:
Сообщение от mazzy
Кто в курсе, NavigationPropertyMethod действительно не поддерживается в D365FO?
просто на этих методах основан Unit Of Work. И теперь получается, что Unit of Work тоже не поддерживается? см. также. https://community.dynamics.com/ax/b/...s/unit-of-work Цитата:
Ну т.е. пока как-то UnitOfWork на меня не произвел должного впечатления. В отличие, кстати, от Navigation Property Methods
__________________
Возможно сделать все. Вопрос времени |
|
09.12.2020, 11:11 | #4 |
Участник
|
Я так понимаю на этих Navigation Property Methods не будут работать перекрестные ссылки? Если так, то наверное лучше их не использовать, не так уж и сложно написать метод для поиска
|
|
09.12.2020, 11:34 | #5 |
Administrator
|
Цитата:
У этих методов есть другой недостаток - насколько я понимаю они могут быть использованы для выборки только на чтение. Т.е. для выборки на изменение все равно придется писать свой метод. А в этом случае тогда ценность Navigation Property Methods сильно снижается. Конечно могут быть ситуации, когда достаточно выбирать только на чтение, но в общем количестве этих ситуаций гораздо меньше общего количества
__________________
Возможно сделать все. Вопрос времени Последний раз редактировалось sukhanchik; 09.12.2020 в 11:36. |
|
09.12.2020, 11:46 | #6 |
Участник
|
ээээ. а что делать с экстеншенами?
и как их использовать в UnitOfWork? Цитата:
Почему бы не спросить авторов этого чуда. Насколько я понимаю: 1. ноги растут из традиционного программирования, где для каждой таблички создается dto-класс. и традиционных ORM. 2. задача - минимизировать операции с базой данных за счет того, что в базу передается не каждое изменение в dto-классе, а некие "значимые состояния" 3. в аксапте типичный где UnitOfWork очень пригодился бы - это InventSumDelta - суммирование происходит "в памяти" транзакция записывает в InventSum только "финальный" итог. В аксапте какой-то деятель начал использовать UnitOfWork совсем для других целей. "Поясню". В аксапте некие другие деятели в 2012 решили перейти на искусственные индексы по RecId. Для этого было добавлена куча пропертей в объектах, добавлены новые понятия типа Replacement Index, введены новые типы контролов, которые автоматически делают разыменование искусственных индексов (но при этом теряют поиск по этому полю ) В принципе, решали проблему "медленной генерации ключевых полей". С прицелом передать генерацию RecId на SQL server. И даже попытаться воспользоваться родным SQL-ным autoIncrement-ом. В общем, решили и сделали. И! вдруг! обнаружили! что искусственные ключи ведут себя совершенно иначе в массовых операциях. как происходят массовые операции для связанных таблиц для "наших" ключей: 1. мы генерим код (обычно вызываем NumSeq) 2. заполняем мастер-справочник данными 3. - 4. заполняем подчиненные справочники данными 5. заполняем в подчиненных справочниках сгенеренный код (который мы знаем) 6. используем какой-нибудь insertRecorset, SortedList для массового обновления данных важно, что шаг 6 легко можно вынести в отдельный метод, который знать ничего не знает о связях, бизнес-логике и прочих "несущественных" мелочах как происходят массовые операции для связанных таблиц для "системных" ключей. 1. - 2. заполняем мастер-справочник данными 3. записываем в БД(!), получаем сгенеренный системой recID 4. заполняем подчиненные справочники данными 5. заполняем в подчиненных справочниках recID 6. записываем данные из подчиненного справочника (уже неважно как) главное, с recID-ключом массовое обновление базы данных идет в пешее иротическое. универсальные методы работы с бд идут туда же. ситуация сильно ухудшается, если мы имеем дело с итерационными процессами типа обновления себестоимости (см. InventSumDelta) =========== естественно, доблестные программисты начали решать "проблему", которую создали архитекторы, абсолютно программистскими методами. См. класс systemSequence и обслуживающий его ужас в виде "appl.sysRecIdSequence()" Ax2009, сбросить кеш recid SystemSequences http://sinedax.blogspot.com/2018/09/...-dynamics.html но это "проблема" чисто программистскими методами не решается, поскольку сидит на архитектурном уровне . Поэтому на программистском уровне пришлось вводить методы suspendRecIds/removeRecIdSuspension до сих пор непонятно приостанавливают ли эти методы выделение recID глобально (для всех потоков) или только для одного потока. Есть разные мнения. но если приостанавливают глобально, то это полный пипец для производительности. на архитектурном уровне suspendRecIds для таблицы тут же запрещает рекурсивные алгоритмы и алгоритмы, которые "внутре" могут вызвать создание записей в этой же таблице. (Прощай деревья!) "Сходили за хлебушком" называется, ускорили индексы заменив "длинные" и составные строковые ключи на "короткие" recID - запретили массовые операциии с БД, ввели stop-world-паттерн, поломали деревья. но даже если suspendRecIds приостанавливает выделение только в области видимости переменной systemSequence, как CodePermission (будь проклят тот архитектор, который принял решение добавить эту хрень в аксапту), то все равно остается непонятным как на самом деле ЭТО ведет себя если будет выброшено исключение (suspendRecIds сработал, а до removeRecIdSuspension не дошли) и что будет с UserConnection... =========== естессно, народ в майкрософте не дурак и видит проблему. но что делать, если решение об искусственных ключах уже принято и кто-то уже отчитался. и тут возник Unit Of Work. который в основе своей использует эти самые навигационные методы... но внезапно(!), видимо, другая команда добавила наследование таблиц в 2012 в результате борьбы бульдогов под ковром (там еще и отдел отчетности встрял) в ax2012sp1 наследование было выброшено на помойку... ну.. как... на уровне SQL никакого наследования нет - все в одной таблице. но зато на уровне AOT совершенно дикое и никем не принятое наследование. Хорошо, сделали Unit Of Work перестал ругаться на наследование. но похоже пришла беда откуда не ждали - extensions в D365 Последний раз редактировалось mazzy; 09.12.2020 в 12:56. |
|
|
За это сообщение автора поблагодарили: trud (2), sukhanchik (8). |
09.12.2020, 12:01 | #7 |
Участник
|
Цитата:
Они наплодили объектов, по которым не генерируются перекрестные ссылки... https://coub.com/view/8jrsb Цитата:
Если я правильно понимаю, 1. поисковый метод сделает отдельный select и получит значения из базы 2. навигационный метод получит значения из UnitOfWork. Это значение может отличатся от того, что лежит в базе из-за операций изменения в UnitOfWork |
|
09.12.2020, 12:56 | #8 |
Участник
|
Цитата:
Сообщение от mazzy
как происходят массовые операции для связанных таблиц для "системных" ключей.
1. - 2. заполняем мастер-справочник данными 3. записываем в БД(!), получаем сгенеренный системой recID 4. заполняем подчиненные справочники данными 5. заполняем в подчиненных справочниках recID 6. записываем данные из подчиненного справочника (уже неважно как) 1. - 2. заполняем мастер-справочник данными // 3. записываем в БД(!), получаем сгенеренный системой recID 3. Генерируем в буфере мастер-справочника RecId, (можно например для этого сделать метод на Common) 4. заполняем подчиненные справочники данными 5. заполняем в подчиненных справочниках RefRecID на мастер-справочник 6. записываем данные из подчиненного справочника (уже неважно как, можно и по старинке) По удобству использования все то же самое как и раньше для естественных ключей. Плюс можно сохранить логику вставки записей - сперва строки, потом шапка, на которую эти строки ссылаются (так много где сделано в ax3-2009) - это может быть полезно в некоторых случаях, когда какой-то подписчик или интеграция с внешней системой отбирает документы по шапкам и хватают еще до конца не сгенерированный документ, так как шапка уже вставилась и куда то вовне уходит часть документа. |
|
|
За это сообщение автора поблагодарили: mazzy (2). |
09.12.2020, 13:03 | #9 |
Участник
|
Цитата:
Именно так и сделали. Цитата:
systemSequence и обслуживающий его ужас в виде "appl.sysRecIdSequence()"
... на программистском уровне пришлось вводить методы suspendRecIds/removeRecIdSuspension ну и далее, что я писал. https://coub.com/view/9qsst добавлено: Причем ладно с логикой и высокими материями типа рекурсии или с исключениями... Но даже метод isSuspendedRecId() не реализовали. Суки. Вот какой-то "архитектор" это ж утверждал. Последний раз редактировалось mazzy; 09.12.2020 в 13:10. |
|
09.12.2020, 13:19 | #10 |
Moderator
|
Мне кажется что эти методы остались еще со времен Axapta 2.x и их просто не перепроектировали в связи с переходом на суррогатные ключи. Просто конечные разработчики, которые, например, логику разноски закупок и заказов писали, вынуждены были от безысходности этот механизм использовать.
|
|
09.12.2020, 13:23 | #11 |
Участник
|
ах, если бы ты был прав.
добавлено: а может быть и suspendRecIds не делает stop-world? может кто знает точно как оно работает? Последний раз редактировалось mazzy; 09.12.2020 в 13:26. |
|
09.12.2020, 13:44 | #12 |
Moderator
|
Цитата:
на всякий случай спрошу - а ты под "потоком" thread в C/C#-смысле подразумеваешь, или аксаптовскую сессию ? |
|
09.12.2020, 14:05 | #13 |
Участник
|
Цитата:
Цитата:
на котором в несколько потоков могут выполняться задания. но ты, конечно, прав, стоит учитывать и просто аксаптовские сессии. в частности, входящие вызовы аксаптовских веб-сервисов. обращения через COM, ну и обычные клиенты конечно. в общем, любое выполнение аксаптовского кода (X++ или CIL) |
|
09.12.2020, 14:26 | #14 |
Moderator
|
Цитата:
Сообщение от mazzy
в рамках аксапты прежде всего имею в виду пакетный сервер,
на котором в несколько потоков могут выполняться задания. но ты, конечно, прав, стоит учитывать и просто аксаптовские сессии. в частности, входящие вызовы аксаптовских веб-сервисов. обращения через COM, ну и обычные клиенты конечно. в общем, любое выполнение аксаптовского кода (X++ или CIL) |
|
09.12.2020, 14:28 | #15 |
северный Будда
|
Цитата:
У меня на проекте из-за этого некоторое время назад пришлось тучу кода перелопатить((((((( который делался ещё в эпоху работавших navigation property...
__________________
С уважением, Вячеслав |
|
|
За это сообщение автора поблагодарили: sukhanchik (4). |
09.12.2020, 15:18 | #16 |
Administrator
|
Сейчас еще (PU38) пока только Intellisense отстает при переопределении названия метода (выпадает не переопределенное название). Но если не обращать внимание на Intellisense - все компилируется без ошибок.
__________________
Возможно сделать все. Вопрос времени |
|
09.12.2020, 16:31 | #17 |
Участник
|
Так а ты думаешь что есть какой-то архитектор языка? ну т.е. может быть он и был, но сейчас что-то я не слышал о такой должности, есть Joris de Gruyter, который такими вопросами особо не интересуется, может быть только исключительно с точки зрения поддержки
|
|
09.12.2020, 16:57 | #18 |
Участник
|
Цитата:
но у каждой конкретной фичи ответственный за нее архитектор есть. как подсказал fed, класс systemSequence существовал еще в ax3.0 как было тогда - не знаю. но вижу, что обвязка "appl.sysRecIdSequence()" появилась в ax2012. вот у нее архитектор был. Был в Майкрософте человек, который принял решение * вместо того, чтобы добавить в ядро, в класс systemSequence метод isSuspendedRecId, * добавить класс-wrapper с Set, а всех программистов заставить соблюдать паттерн "appl.sysRecIdSequence()" (иначе класс-wrapper будет работать неправильно) |
|
09.12.2020, 17:54 | #19 |
Участник
|
Не. Я по другое.
Я вот подумал, а что мешало сделать kernel метод на буфере - выделить RecId и заполнить им поле common.RecId и взвести флажок чтобы на вставке оно не перезатиралось. Самое простое и удобное решение. И никаких огородов городить не надо с SystemSequence |
|
09.12.2020, 18:33 | #20 |
Участник
|
А...
изначально хотели отдать генерацию recID SQL-серверу. |
|
|
|