14.03.2012, 18:15 | #1 |
Участник
|
Аккуратнее! ValidateDelete() на таблице не всегда спасет.
Когда просят сделать запрет на удаление записи в таблице, программисты, очень часто, прибегают к самому простому способу - перекрыть метод ValidateDelete(). Сегодня нактнулся на такую особенность. Предположим у вас есть 2 таблицы : Table и Line. В таблице Line настроен Relation на таблицу Table и перекрыт метод ValidateDelete() на различные дополнительные проверки во время удаления записи. А в таблице Table настроен DeleteActions: Cascade на таблицу Line. Удаление строки в таблице Table с легкостью удалит связанные строчки в Line, несмотря на все проверки.
Вывод : Каскадное удаление игнорирует метод ValidateDelete(). Поэтому перед перекрытием этого метода пробежаться по Relation-ам и посмотреть на существование DeleteActions в связанных таблицах лишним не будет. Может быть этот баг (или фича, в чем я крайне сомневаюсь) был уже описан здесь. Но по поиску не нашел. Для нас это хорошо, что обнаружилось заранее. AX 2009 RU5.
__________________
-Ты в гномиков веришь? -Нет. -А они в тебя верят, смотри, не подведи их. |
|
14.03.2012, 18:52 | #2 |
Участник
|
Цитата:
1. Методы ValidateDelete, ValidateField вызываются ядром ТОЛЬКО при интерфейсных операциях (пользователь что-то делает на форме). 2. В остальных случая эти методы должны вызываться явно в коде Это фича. Об этом даже вопросы на экзамене были, насколько я помню. |
|
|
За это сообщение автора поблагодарили: Pustik (2). |
14.03.2012, 19:03 | #3 |
Участник
|
Спасибо, не знал. А по чему так сделали? Ведь было бы удобно. Может быть есть ссылки?
__________________
-Ты в гномиков веришь? -Нет. -А они в тебя верят, смотри, не подведи их. Последний раз редактировалось Pustik; 14.03.2012 в 19:07. |
|
15.03.2012, 00:39 | #4 |
Участник
|
1) почему пишется слитно
2) так сделано, чтобы был выбор - ограничивать только на форме или везде 3) еще у таблицы есть методы delete() и aosValidateDelete(), которые тоже можно перекрыть |
|
|
За это сообщение автора поблагодарили: driller (0). |
15.03.2012, 07:53 | #5 |
Enjoy!
|
Цитата:
Посмотрел - действительно так! А какой validate delete метод не будет пропускать в при DeleteActions: Cascade? Последний раз редактировалось iCloud; 15.03.2012 в 08:09. |
|
15.03.2012, 09:33 | #6 |
Участник
|
Цитата:
X++: public void delete() { if (!this.validateDelete()) throw exception::error; super(); } |
|
15.03.2012, 09:34 | #7 |
Участник
|
К стати, методы Write() и modifiedField() также вызываются только через пользовательский интерфейс.
Нужно помнить, что интерфейсные события это всего лишь события изменения клиентского курсора а не строки в БД. Если одновременно с созданием/изменением/удалением какй-то строки нужно синхронно изменять ещё что-то в другой строке или другой таблице, то для обеспечения целостности данных делать это нужно внутри транзакции в методах Insert/Update/Delete. Распознать факт изменения конкретного поля на уровне метода Update можно сравнением текущего(изменённого) значения this.Field и оригинального this.orig().Field. Последний раз редактировалось S.Kuskov; 15.03.2012 в 09:37. |
|
|
За это сообщение автора поблагодарили: Pustik (2), iCloud (1). |
16.03.2012, 08:29 | #8 |
Участник
|
Чего-то не понимаю из-за чего паника?
Если настроено каскадное удаление, то зачем в таблице Line нужны записи не имеющие связной записи в таблице Table? Это типа как Журнал приказа удалить, а строки этого приказа оставить. Только вот зачем нужны эти строки без Журнала. Или я что-то не так понял? |
|
16.03.2012, 09:18 | #9 |
Участник
|
Угу, не так
Речь шла о том что если на "строках" удаляемого "журнала" есть собственный validateDelete(), который не позволяет удалить такую строку (ну допустим, пока её не "разутвердят"), то такая проверка не сработает в случае каскадного удаления ("неразутверждённые" строки удалятся) . А хотелось, что бы в таком случаее удаление "журнала" (всего журнала: и шапок и строчек) прерывалось. Другими словами, нет желания удалить часть связанных данных, есть желание предотвратить удаление всех данных, если хотя бы их часть не подлежит удалению. Вывод: validateDelete() не является инструментом сохранения целостности данных. Это всего лишь часть презентационной логики UI. Последний раз редактировалось S.Kuskov; 16.03.2012 в 09:45. |
|
16.03.2012, 18:30 | #10 |
Участник
|
После каждого предложения ставится орфографический знак - точка.(или восклицательный или вопросительный знак).
А разве validateDelete() на датасорсе формы отменили? Чем же они тогда отличаются?
__________________
-Ты в гномиков веришь? -Нет. -А они в тебя верят, смотри, не подведи их. |
|
16.03.2012, 22:40 | #11 |
Участник
|
Цитата:
Это обертки - каждый из этих методов просто вызывает соответствующий метод таблицы, но может быт перекрыт. А в фреймворке формы прописан вызов validateDelete() датасорса перед вызовом delete() датасорса. Это как fieldModified(). Если ввод данных происходит не через форму, то его нужно явно вызывать. На обычное присвоение триггер не сработает
__________________
If it ain't broke, take it apart and find out why (с) |
|