Как диагностировать ArgumentOutOfRangeException для SqlDbType?
У нас есть некоторые клиенты, использующие наше приложение для толстых клиентов.NET 2.0, которые испытывают странные, периодически возникающие ошибки при чтении данных с сервера SQL 2000 SP4, где действия были успешными всего несколько минут назад. У нас есть клиенты, использующие SQL 2000 (и многие, использующие 2005), где эти ошибки не возникают.
Я заметил одну вещь: приложение в наших средах тестирования ссылается на System.Data 2.0.50727.3053; тогда как приложение ссылается на 2.0.50727.1433 по системам заказчика. В чем разница между этими двумя версиями и может ли это быть связано с ошибками, описанными ниже?
Вот пример трассировки стека ошибки, где значение перечисления равно 8, но у меня есть еще много случаев, когда значение перечисления "вне границ" равно 4 или 14 с той же точной трассировкой стека. Значения перечисления можно найти иногда, но не в другое время? Что делать, когда одна и та же часть приложения работает без ошибок?
TYPE: System.ArgumentOutOfRangeException
MSG: The SqlDbType enumeration value, 8, is invalid.
Parameter name: SqlDbType
SOURCE: System.Data
SITE: GetSqlDataType
at System.Data.SqlClient.MetaType.GetSqlDataType(Int32 tdsType, UInt32 userType, Int32 length)
at System.Data.SqlClient.TdsParser.CommonProcessMetaData(TdsParserStateObject stateObj, _SqlMetaData col)
at System.Data.SqlClient.TdsParser.ProcessMetaData(Int32 cColumns, TdsParserStateObject stateObj)
at System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj)
at System.Data.SqlClient.SqlDataReader.ConsumeMetaData()
at System.Data.SqlClient.SqlDataReader.NextResult()
at Ceoimage.Basecamp.Data.Document._GetDocumentModelWithCollections(IDataReader rdr)
Обновление: я только что загрузил System.Data с одной из рабочих станций клиентов. У них было две версии в GAC, одна в каталоге GAC и одна в каталоге GAC_32. В GAC номер версии - 1.14322.2365. В GAC_32 номер версии равен 2.0.50727.1433, как описано выше. Однако во всех трех версиях перечислимый SqlDbType отображает одни и те же значения типа int на те же типы, что и в сообщениях об ошибках:
DateTime = 4
Int = 8
UniqueIdentifier = 14
Я боюсь, что версия может быть красной сельдью: если проблема связана с версиями фреймворка, разве проблема не должна происходить 100% времени, а не быть временной?
3 ответа
Эта древняя дискуссия отслеживает похожую ошибку вплоть до использования соединения, созданного в одном потоке, для выполнения запроса в другом потоке. SqlConnection "членам экземпляров не гарантируется поточно-ориентированная безопасность". Если ваше приложение является многопоточным, убедитесь, что соединения используются правильно.
Проблема также может быть связана с SQL-Server, которая была решена в более поздних версиях.
Я отвечаю здесь, потому что я столкнулся с этой ошибкой при использовании SqlCommand.Cancel с SQL 2005. (Есть несколько исключений, которые происходят в дополнение к "Операция отменена пользователем" в зависимости от того, когда запрос отменен.) Я вижу это как "неожиданный ответ от сервера" ошибка... вероятно, будет хорошей идеей очистить пул соединений, если это произойдет.
Как отменить длительную операцию базы данных?
Как принудительно физически закрыть SqlConnection при использовании пула соединений?
Ваш клиент на.NET 2.0 без 3.5 установлен. Ваши тестовые серверы 3.5. Единственное, что добавлено в перечисление в 3.5:
Structured
Date
Time
DateTime2
DateTimeOffset
Это не означает, что нет каких-либо изменений в основе.
Если возможно, я бы протестировал приложение под 2.0 без 3.5 и посмотрел, какие ошибки вы получаете. Это должно дать вам хорошее место для начала.
Чтобы выяснить причину ошибки, мне пришлось бы пройтись по перечислению и посмотреть, в каком порядке расположены элементы в перечислении. Reflector - отличный инструмент для этого, но вам придется сделать это как в системе 2.0, так и в системе 3.5, чтобы увидеть изменения.
Это решение может решить вашу проблему:
Использует ли ваш локальный компьютер SQL Server 2008, а другой - 2005? Параметр @RUNTIME имеет тип SqlDbType.Time. Этот тип не существовал в SQL Server 2005. Кроме того, SqlDbType.Time имеет значение 32, как говорит исключение. Вы не можете хранить только значения времени до SQL Server 2008. Вы должны хранить @RUNTIME как SqlDbType.DateTime в 2005 году.
И если вы используете .NET Framework 2.0, используйте для установки этой проблемы .NET Framework 2.0 SP2 и sql2008.