Используя ODBCDataReader, почему я не могу обнаружить DBNull в поле, используя DBNull.Ценность.Равно или IsDBNull в vb.net ? Определенно DBNull

#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))