|
22.04.2011, 15:24 | #1 |
Участник
|
BusinessConnector .Net - исключение при вызове AxaptaRecord.Write
Доброго времени суток.
При создании объекта AxaptaRecord и вызове метода AxaptaRecord.Write после нескольких десятков удачных повторов в конце концов получаю одно из исключений: а) AccessViolationException б) SEHException (внешний компонент создал исключение) Подскажите, может известна какая-то причина, или с чего, хотя бы, начать с этим разбираться? Спасибо. Последний раз редактировалось Evgenius; 22.04.2011 в 15:27. |
|
22.04.2011, 16:41 | #2 |
Участник
|
а как получаете курсор AxaptaRecord? Ну, например, IAxaptaRecordAdapter currentRecord = AxBaseWebPart.GetWebpart(this).ExternalRecord.
|
|
22.04.2011, 17:10 | #3 |
Модератор
|
А с правами все ок?
С Уважением, Георгий |
|
22.04.2011, 17:56 | #4 |
Участник
|
Проверь наличие уникальных индексов на таблице.
Возможно, ты пытаешься создать дублирущие записи.
__________________
Ален ноби, ностра алис. Что означает - если один человек построил, другой завсегда разобрать может. |
|
03.05.2011, 07:40 | #5 |
Участник
|
Я прошу прощения, что исчез из собственной темы - пытался переделать приложение.
Ошибки возникают все равно, гадать больше не хочется. Уточнения: Цитата:
Цитата:
Сообщение от George Nordic
А с правами все ок?
Цитата:
Сообщение от dmitro
а как получаете курсор AxaptaRecord? Ну, например, IAxaptaRecordAdapter currentRecord = AxBaseWebPart.GetWebpart(this).ExternalRecord.
X++: axRecord = Axapta.CreateAxaptaRecord(< >); axRecord.ExecuteStmt("select * forupdate from %1"); if (axRecord.Found) ... |
|
03.05.2011, 09:45 | #6 |
MCT
|
В аксе при использовании конструкции forupdate требуется еще ttsbegin делать, возможно это оттуда.
__________________
Axapta book for developer |
|
03.05.2011, 11:42 | #7 |
Участник
|
Цитата:
это обычное Net-приложение, так что используется BusinessConnectorNet:
X++: axRecord = Axapta.CreateAxaptaRecord(< >); axRecord.ExecuteStmt("select * forupdate from %1"); if (axRecord.Found) ... |
|
03.05.2011, 12:02 | #8 |
MCT
|
2Evgenius
действительно опубликуйте, весь код, что бы не гадать.
__________________
Axapta book for developer |
|
03.05.2011, 14:57 | #9 |
Участник
|
1. ttsbegin присутствует
2. 2dmitro. Вы как думаете, смог бы я часть записей создавать успешно (см. первый пост), если бы не залогинился? 3. 2Miker. Опубликовать целое .Net-приложение? Если у вас есть список возможных причин - поделитесь, пожалуйста, если нет - значит, вы именно гадать и собирались, разве нет?:-) В сухом остатке: отсутствие TTSBegin - не причина, разве что я его неправильно использую. Сейчас на всякий случай делаю так: вызываю в начале процедуры, где изменяю запись таблицы, а в конце этой процедуры всегдда вызываю TTSCommit, даже если не изменилось ничего. Что еще может быть? |
|
03.05.2011, 15:39 | #10 |
MCT
|
Цитата:
А по коду можно многое сказать, выложите именно те вещи которые совершают вызовы методов нет коннектора от начала до конца. Остальное можете убрать и поставить звездочки. X++: *****
__________________
Axapta book for developer |
|
03.05.2011, 15:57 | #11 |
Участник
|
Давно известно, что когда код вынужденно разбит на кучу процедур и потому состоит из одних вызов, он вызывает только вопросы.
Ну, попробуем: X++: AxaptaRecord axRecord = AX.CreateAxaptaRecord("PST_Inventory_ItemProperties"); Int64 RecId = 0; // определить тип данных InventoryDataTypes DataType = GetInventoryDataType(PropertyType); // конвертировать значение из строки (если нужно) и установить в нужное поле string FieldName; object DBPropertyValue = ConvertToInventoryDataType(PropertyType, PropertyValue, AssociatedLink, out FieldName); if (DBPropertyValue == null) return 0; axRecord.set_Field(FieldName, DBPropertyValue); if (FieldName != "Link" && AssociatedLink != null) axRecord.set_Field("Link", AssociatedLink); else if (FieldName != "StringValue" && Convert.ToString(DBPropertyValue) != PropertyValue) axRecord.set_Field("StringValue", PropertyValue); // заполнить прочие нужные поля записи axRecord.set_Field("ItemType", (int)ItemType); axRecord.set_Field("ItemRecId", ItemRecId); axRecord.set_Field("DataSourceId", DataSourceId); axRecord.set_Field("PropertyType", PropertyType.ID); // поскольку мы не получаем группы отдельно (только вместе с элементами), // то указываем группу, только если она только что загружена PropertyTypeGroup PropertyGroup = (PropertyTypeGroup)PropertyGroups[Convert.ToInt64(PropertyGroupId)]; if (PropertyGroup != null) { axRecord.set_Field("PropertyGroupId", PropertyGroup.RecordID); } axRecord.set_Field("LanguageId", LanguageId); try { if (axRecord.ValidateWrite()) { axRecord.Write(); RecId = (Int64)axRecord.get_Field("RecId"); } } catch (Exception ExceptionData) { throw ExceptionData; } Комментарии это код из отдельной процедуры, метод TTSBegin вызывается До нее, а TTSCommit -после. При ошибке сообщается, что она произошла в ValidateWrite(), но на таблице нет ни отношений, ни уникальных индексов, ни перекрытого метода ValidateWrite(). Обязательные поля заполнены все. Последний раз редактировалось Evgenius; 03.05.2011 в 16:08. |
|
03.05.2011, 17:18 | #12 |
MCT
|
ну начинать надо по порядку :
1 axRecord то вообще создает запись, без последующего обновления? то есть закоментить write() и вызвать insert().
__________________
Axapta book for developer |
|
03.05.2011, 18:11 | #13 |
Участник
|
Это работает в нескольких приложениях, разработанных для обмена данными со сторонними системами. В чем тут проблема? Я понимаю, что метод insert может содержать что-то дополнительное, но здесь НЕ содержит. Точно. Вообще, у всех тутошних таблиц пока что НЕ ПЕРЕКРЫТ ни один метод.
Последний раз редактировалось Evgenius; 03.05.2011 в 18:14. |
|
03.05.2011, 21:10 | #14 |
Участник
|
Цитата:
В идеале, перехватить ошибку и сбросить в лог значения всех полей той записи, которая создается/модифицируется. Или просто на этапе отладки перед выполнением проблемного метода сбрасывать значения всех полей в лог. |
|
|
За это сообщение автора поблагодарили: Evgenius (1). |
03.05.2011, 22:41 | #15 |
Участник
|
Цитата:
Сообщение от Владимир Максимов
Надо еще проверить, что поля заполнены допустимыми значениями. Не только обязательные для заполнения, а вообще все. Ну, например, нет ли где попытки записать значение NULL?
В идеале, перехватить ошибку и сбросить в лог значения всех полей той записи, которая создается/модифицируется. Или просто на этапе отладки перед выполнением проблемного метода сбрасывать значения всех полей в лог. (насчет явной установки null можно не беспокоиться - метод AxaptaRecord.set_Field не допускает такие значения) |
|
04.05.2011, 15:29 | #16 |
Участник
|
Цитата:
Сообщение от Владимир Максимов
Надо еще проверить, что поля заполнены допустимыми значениями. Не только обязательные для заполнения, а вообще все. Ну, например, нет ли где попытки записать значение NULL?
В идеале, перехватить ошибку и сбросить в лог значения всех полей той записи, которая создается/модифицируется. Или просто на этапе отладки перед выполнением проблемного метода сбрасывать значения всех полей в лог. А нет ли какого способа получать информацию о причинах ошибки (почему "внешний компонент вызвал исключение" и т.п.)? Или можно только доработать свои таблицы, чтобы хоть с ними было ясно? |
|
03.05.2011, 18:28 | #17 |
Участник
|
Ситуация изменилась после того, как я "наудачу" выделил приведенный код в отдельную транзакцию (потому что он использует некоторые им же добавленные данные):
Теперь приложение вылетает на ошибку: Цитата:
Имя сбойного приложения: *******.vshost.exe, версия: 9.0.30729.4462, отметка времени: 0x4b2c8d75
Имя сбойного модуля: ntdll.dll, версия: 6.1.7600.16695, отметка времени 0x4cc7b325 Код исключения: 0xc0000374 Смещение ошибки: 0x00000000000c6ab2 Идентификатор сбойного процесса: 0x6664 Цитата:
Object Server 01: Attempt to clear pointerMap when it still contains objects
|
|
04.05.2011, 11:35 | #18 |
Участник
|
Цитата:
Сообщение от Evgenius
Ситуация изменилась после того, как я "наудачу" выделил приведенный код в отдельную транзакцию (потому что он использует некоторые им же добавленные данные):
Теперь приложение вылетает на ошибку: А на сервере есть следующий комментарий: Так что теперь еще и с этим пытаюсь разобраться (нормальная работа теперь продолжается дольше, так что, м.б. изменения к лучшему:-)). |
|
04.05.2011, 13:18 | #19 |
Участник
|
Цитата:
Сообщение от dmitro
а здесь смотрели http://community.dynamics.com/produc...967/86261.aspx? Последние два сообщения.
|
|
04.05.2011, 11:34 | #20 |
Участник
|
Ну, как пример.
Предположим, что поле LanguageId создано на основе Extended Data Types с тем же именем LanguageId. Этот Extended Data Types имеет Relations настроенный на таблицу LanguageTable. Следовательно, поле LanguageId может принять только те значения, которые есть в таблице LanguageTable и соответствуют всем дополнительным условиям связи, указанным в Relations. Это значит, что, например, если в таблице LanguageTable нет языка с кодом "XXX", то при попытке сохранить сделанные изменения Вы получите сообщение об ошибке о том, что такого значения не существует в связанной таблице. НО! Подобный контроль корректности введенного значения будет выполнен только при интерактивном вводе (через форму ввода). При программном вводе подобная проверка не осуществляется. Однако, это из среды Axapta. Как оно работает через Connector - не проверял. Теоретически - не должно, но проверить не помешает... PS: Если значение поля явно не указано, то оно принимает пустое значение. Не NULL, а именно пусто. Что именно подразумевается под "пустым" значением зависит от типа данных. Для числовых значений (включая Enum) - это 0, для строковых - пустая строка, для дат - 01.01.1900 |
|
Теги |
business connector, com connector |
|
Опции темы | Поиск в этой теме |
Опции просмотра | |
|