#vb.net #null #odbc #quickbooks #dbnull
#vb.net #null #odbc #быстрые книги #dbnull
Вопрос:
Я знаю, что это действительно DBNull, когда я использую String .IsNullOrEmpty выдает ошибку «Не удается преобразовать тип DBNull в тип String»
Я использую ODBCDataReader со следующей OdbcCommand для передачи из файла Quickbooks Desktop company в базу данных SQL через LINQ; не уверен, что это особенность ODBC или что-то в этом роде, поскольку я использую его впервые:
SELECT id, string0, string1, string2, string3, int FROM Table1 WHERE (IsActive = 1)
Для обработки результата я использую:
IIf(IsDBNull(e(3)) Or IsNothing(e(3)), String.Empty, e(3))
Таблица, в которую я переношу, не допускает нулей.
Я пробовал использовать Not и менять местами результирующие параметры, я пробовал использовать Is Nothing и DBNull .Значение.Equals() и, конечно, IsNullOrEmpty . Когда у меня нет IsNullOrEmpty в инструкции, я получаю «Невозможно вставить NULL в таблицу», я также пробовал поменять местами или с помощью OrElse. Как упоминалось ниже, я все равно должен использовать OrElse.
Теперь, с другой таблицей в том же файле company, этот код отлично работает с DBNulls. Я скопировал код напрямую и перепробовал все комбинации вещей, которые я могу придумать. Что может быть не так с этим экземпляром, что может привести к тому, что он не распознает тип поля?
Если вы можете указать мне правильное направление, я был бы очень признателен.
Ответ №1:
Что вас сбило с толку, так это то, что Or
в VB.NET является ли базовый дон тем, что есть в VB6, который не закоротил логику:
https://docs.microsoft.com/en-us/dotnet/visual-basic/language-reference/operators/orelse-operator
Попробуйте это вместо:
IIf(IsDBNull(e(3)) OrElse IsNothing(e(3)), String.Empty, e(3))
Комментарии:
1. Да, я забыл это добавить. Это одна из тех вещей, которые я пробовал, но я буду иметь это в виду на будущее. Я обновлю сообщение.
Ответ №2:
Это:
IIf(IsDBNull(e(3)) Or IsNothing(e(3)), String.Empty, e(3))
это мусор по очень многим причинам.
Переходя к делу, DBNull.ToString
возвращает пустое String
значение so, если вам нужно String
, если оно существует, или пустое String
значение для NULL, тогда все, что вам нужно сделать, это вызвать ToString
:
Dim str = myDataReader(columnIndex).ToString()
Однако, игнорируя это, вы НИКОГДА не должны использовать IIf
, IsDBNull
, или IsNothing
и, как уже было установлено, вы должны в значительной степени ВСЕГДА использовать AndAlso
и OrElse
, а не And
и Or
. Последнее следует использовать только тогда, когда вы хотите специально избежать короткого замыкания, и в этом случае ваш код, вероятно, плох по другим причинам.
Итак, вместо IIf
функции, которая с самого начала была мусором, вы должны использовать If
оператор, который был введен в VB 2008. Существуют различные способы проверки DBNull
, и средство чтения данных предоставляет свои собственные. Есть также лучшие способы проверки Nothing
, но здесь это все равно бессмысленно, потому что вы никогда не сможете получить Nothing
доступ из базы данных.
Допустим, вы использовали числовой столбец, а не текст, и вы хотели использовать ноль вместо нулевых значений. Правильный способ написания кода, как у вас, был бы следующим:
Dim num = If(myDataReader.IsDBNull(columnIndex), 0, myDataReader.GetInt32(columnIndex))
Как я уже сказал, средство чтения данных само может сообщить вам, является ли столбец NULL . If
Оператор фактически является универсальным, что означает, что два возможных возвращаемых значения должны быть одного типа или один тип должен быть производным от другого. В этом примере оба типа являются типом Integer
, так что все в порядке. Если бы вы хотели выполнить бессмысленную проверку Nothing
, это выглядело бы так:
Dim num = If(myDataReader.IsDBNull(columnIndex) OrElse myDataReader(columnIndex) Is Nothing,
0,
myDataReader.GetInt32(columnIndex))