10.01.2017, 11:46 | #1 |
Участник
|
xRecord.isFieldSet() - что это? как сейчас правильно проверять наличие поля в базе данных?
https://msdn.microsoft.com/en-us/lib...sfieldset.aspx
xRecord.isFieldSet() - что это? как сейчас правильно проверять наличие поля в базе данных? причем в ax2012 этот метод почти не используется, судя по перекрестным ссылкам. а в ax7 этот метод используется, похоже, для проверки существования поля в базе. (вместо нормальных dictTable) А что это за хрень-метод? и что за свойство может быть установлено в "a Set or Defaulted state; otherwise..."? |
|
10.01.2017, 12:46 | #2 |
Участник
|
true if field is has a Set or Defaulted state; otherwise, false.
То есть было ли залито какое-то недефолтное значение в заданное поле. |
|
|
За это сообщение автора поблагодарили: mazzy (2). |
10.01.2017, 13:03 | #3 |
Участник
|
Цитата:
См. также давнишнее обсуждение В чем преимущество ax-классов перед непосредственной работой с таблицами? Последний раз редактировалось gl00mie; 10.01.2017 в 13:07. |
|
|
За это сообщение автора поблагодарили: mazzy (2), Logger (1). |
10.01.2017, 13:06 | #4 |
Участник
|
Я бы это перевел как "true - если в поле задано какое-то значение или стоит значение по умолчанию. Иначе false". Может этот метод проверяет null значения ?
Кстати, подчеркнутый код какой то странный. X++: if (!fieldId && !_common.isFieldSet(fieldId)) X++: _common.isFieldSet(fieldId) Может имелось в виду X++: if (!fieldId || !_common.isFieldSet(fieldId)) Последний раз редактировалось Logger; 10.01.2017 в 13:08. |
|
|
За это сообщение автора поблагодарили: mazzy (2), S.Kuskov (1). |
10.01.2017, 13:09 | #5 |
Дмитрий Ерин
|
Как я понял, это просто "признак редактирования" - устанавливается после любой записи в поле и сбрасывается после clear() / update():
X++: static void Job(Args _args) { FieldId fieldId = fieldNum(CustTable, AccountNum); CustTable custTable; ttsBegin; info(strFmt('%1', custTable.isFieldSet(fieldId))); // false custTable.AccountNum = "XXX"; info(strFmt('%1', custTable.isFieldSet(fieldId))); // true custTable.clear(); info(strFmt('%1', custTable.isFieldSet(fieldId))); // false select forupdate firstonly custTable; info(strFmt('%1', custTable.isFieldSet(fieldId))); // false custTable.AccountNum = ""; info(strFmt('%1', custTable.isFieldSet(fieldId))); // true custTable.doUpdate(); info(strFmt('%1', custTable.isFieldSet(fieldId))); // false ttsAbort; }
__________________
|
|
|
За это сообщение автора поблагодарили: mazzy (5), Logger (1), dech (4). |
10.01.2017, 13:23 | #6 |
Участник
|
Цитата:
То есть если вы в табличный буфер что-то записали, состояние поля изменится. |
|
|
За это сообщение автора поблагодарили: mazzy (2), Logger (1). |
10.01.2017, 13:27 | #7 |
Участник
|
ага. понятно - дефолтные значения.
Цитата:
а как сейчас работает логика defaulting'а? сейчас это просто значение, отличное от записанного в базу? или как-то по-другому? |
|
10.01.2017, 15:06 | #8 |
Banned
|
Цитата:
как думаю initValue() делает defaulting. И получается что то что не охвачено initValue() или присвоением значения становится "Not in Use" и имеет isFieldSet как false? Чтобы избежать неуправляемого defaulting? |
|
|
За это сообщение автора поблагодарили: mazzy (2). |
10.01.2017, 15:45 | #9 |
Banned
|
Цитата:
Скобки. Главное сейчас согласится или нет что isFieldSet дает true если (Set or Defaulted state). И понять что такое Defaulted. |
|
10.01.2017, 15:59 | #10 |
Banned
|
https://ax.help.dynamics.com/en/wiki...elds/#defaults
DataEntity.initValue: A data entity is initialized with default values and by using any custom logic that is present in entity-level initValue. This method isn’t called automatically when an insert or update is performed on a data entity from X++. It must be called explicitly if it’s required. The method is called automatically by the form engine when a new record is created. DataEntity.initValue doesn’t call the initValue method for back-end tables that are used in the data entity. Table.initValue: Table-level initValue, as defined for back-end tables, is fired when you perform a data entity insert. This is true for all paths (X++, OData, and so on). Table.initValue is run just before the entity is mapped to data source fields. Можно предположить что все default state случается при вызове super() в initValue(). И Set state при присвоении значения оператором присвоения. Чисто фантазирую. |
|
10.01.2017, 17:11 | #11 |
Участник
|
Цитата:
Или бывает такое, что в пределах от 1 до table.fieldCnt() есть что-то, не имеющее идентификатора поля? |
|
10.01.2017, 17:35 | #12 |
Участник
|
ну... там вообще нужно было бы использовать SysDictTable.fields() и енумератор.
но не будем придираться к оформлению. со стороны ритейл-модулей много кода от людей, которые похоже плохо знают аксапту ) а вот isFieldSet... это уже бизнес-логика. Последний раз редактировалось mazzy; 10.01.2017 в 17:38. |
|
10.01.2017, 17:37 | #13 |
Banned
|
Цитата:
Сообщение от Raven Melancholic
Больше похоже, что код вообще непонятно что делает. Как может быть fieldId == 0, если этот fieldId только что получен при помощи table.fieldCnt2Id(...) вызываемого при переборе полей из SysDictTable.
Или бывает такое, что в пределах от 1 до table.fieldCnt() есть что-то, не имеющее идентификатора поля?
Кто его знает что они накрутили сейчас. От AX2012 уже много что отличается. |
|
11.01.2017, 09:12 | #14 |
Участник
|
Цитата:
False, если поле вообще не трогали.
__________________
// no comments |
|
11.01.2017, 11:12 | #15 |
Участник
|
Цитата:
По-моему, тут о разных понятиях речь. В моем понимании задача логики defaulting'а - неявно подтягивать значения по умолчанию либо значения связанных полей на основе тех полей, которые заданы явно. Например, проставили в шапку заказа на продажу код клиента - defaulting должен подтянуть из клиента фин.аналитики, адрес доставки, способ оплаты, налоговую группу, etc. Особенность работы defaulting'а была и есть в том, что он не должен перезаписывать явно заданные "извне" значения, скажем, если мы вместе с кодом клиента явно прописали адрес доставки не по умолчанию, до defaulting не должен его перезаписывать "своим" значением. Именно для отслеживания того, какие поля были заданы, а какие нет, и использовался прежде метод isFieldSet(). В том числе он использовался для того, чтобы в defaulting'е одного поля понять, было ли задано явно или "по умолчанию" другое поле. Цитата:
Возможно, люди, писавшие ритейл-модуль, просто гоняли тесты производительности перед выпуском, посмотрели в каком-нить профайлере, сколько новых объектов в памяти генерит вызов SysDictTable.fields(), сопоставили это с особенностью работы сборщика мусора в CIL, ужаснулись - и сделали перебор полей по-старинке |
|
|
За это сообщение автора поблагодарили: mazzy (2), Logger (3), ax_mct (4). |
11.01.2017, 15:51 | #16 |
Banned
|
Как понимаю все сходится на том что .isFieldSet() аналог "isTouched including defaulting".
Интересный вопрос в каком случае имеем Default state для поля. и будет ли данный Default state установлен (и как результат .isFieldSet() == true) при вызове super() в initValue(). Предполагаемые варианты получения Default state == true Вариант 1: значение, отличное от записанного в базу Вариант 2: дефолтное присваивание, если отличается от варианта 1. Например присваивание сделанное в initValue() Вариант 3. вызов super() в initValue(). То есть Default state не может получаться при использовании оператора присваивания. Лично мне ближе Вариант 3. Цитата:
Цитата:
Цитата:
Сообщение от gl00mie
Не важно значение поля, важен факт того, было ли оно явно установлено.
... В моем понимании задача логики defaulting'а - неявно подтягивать значения по умолчанию либо значения связанных полей на основе тех полей, которые заданы явно. ... В общем, действительно, дело в том, трогали ли поле |
|
11.01.2017, 17:54 | #17 |
Участник
|
Ну просто значение, записанное в initValue явно не отследишь как дефолтное. Мало ли как его записали (непосредственно в initValue, в методе, вызванном из initValue или как-то еще).
|
|
11.01.2017, 20:09 | #18 |
Banned
|
Цитата:
Но это я фантазирую, проверить нет возможности сейчас. |
|