2010-07-28 4 views
1

Я хочу инициализировать класс данными из MySql db. Некоторые поля могут быть пустым:VB.NET 2010 и MySql - обработка DB NULL для ленивых людей

Dim dr As MySqlDataReader = ... 
Dim item As New Item(dr.GetInt16(0), dr.GetString(1), dr.GetString(2)) 

Предположим, что последние два поля могут быть NULL в БД, так что вызов GetString на этом поле вызывает исключение.

Я мог бы, конечно, написать код для проверки на значения NULL, прежде чем я каждое поле:

dim field1 as String 
if (dr.IsDbNull(1)) 
    field1 = Nothing     ' or even "" 
else 
    field1 = dr.GetString(1) 

Но если у вас есть много полей, это «если» кошмар.

С этой целью я переписал функцию IIf VB, чтобы сделать его более напечатанным, таким образом, чтобы избежать слепков:

Namespace Util 

Public Shared Function IIf(Of T)(ByVal condition As Boolean, ByVal iftrue As T, ByVal iffalse As T) As T 
     If condition Then Return iftrue Else Return iffalse 
End Function 

Так что я мог бы написать что-то вроде:

Dim item As New Item(
    dr.GetInt16(0), 
    Util.IIf(dr.IsDbNull(1), "", dr.GetString(1), 
    Util.IIf(dr.IsDbNull(2), "", dr.GetString(2)) 

Типизированных IIf хорошо работает в других случаях, но, к сожалению, этого не происходит, потому что является обычной функцией, а не ключевым словом языка, каждый параметр inpout оценивается во время ca ll, а когда поле NULL, исключение возбуждается.

Можете ли вы придумать элегантное, если угодно, решение?

ответ

0

Во-первых, я бы рекомендовал вам использовать ORM-карту - сейчас очень мало случаев, когда вам нужно делать ручное «сопоставление».

Если это один из этих случаев, я бы рекомендовал вам использовать имена полей вместо индексов во время доступа к Data Reader.

И чтобы ответить на ваш первоначальный вопрос: попробуйте методы расширения. Извините за C#, но синтаксис VB.NET меняет гайки:

public static class DbDataReaderExtensions 
{ 
    public static T GetField<T>(this DbDataReader dbDataReader, string fieldName, 
     T defaultValue) 
    { 
     if(dbDataReader.IsDBNull(fieldName)) 
      return defaultValue; 
     return (T)dbDataReader[fieldName]; 
    } 
} 
+0

Преобразование типов в порядке: добавить реализации 'DbDataReader', сделать это внутренне, когда вы вызываете строго типизированные функции, такие как' GetString'. –

0

Спасибо.

Я рассмотрел множество ORM, и по тем или иным причинам они мне не нравятся, поэтому я решил вызвать простые хранимые процедуры для получения данных. Можете ли вы советовать что-то мощное, но простое?

Вы правы, чтобы использовать имена полей, это безопаснее, даже если немного медленнее.

Я только что прибыл к такому же выводу с методом, но то, что я до сих пор не нравится это преобразование типов:

Public Shared Function IfNull(Of T)(ByVal dr As MySqlDataReader, ByVal index As Integer, ByVal _default As T) As T 
     If dr.IsDBNull(index) Then 
      Return _default 
     Else 
      Return CType(dr.GetValue(index), T) 
     End If 

End Function 

Я хотел бы сделать что-то более изящное, чтобы получить «реальный» тип данных от читателя.