VB.NET 2010 и MySql - обработка пустых значений БД для ленивых - PullRequest
1 голос
/ 28 июля 2010

Я хочу инициализировать класс данными из базы данных MySql.Некоторые поля могут быть нулевыми:

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)

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

С этой целью я переписал функцию 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 хорошо работает в других случаях, но, к сожалению, в данном случае это не так, поскольку , будучи обычной функцией, а не ключевым словом языка , оценивается каждый входной параметрво время вызова и когда поле имеет значение NULL, возникает исключение.

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

Ответы [ 2 ]

0 голосов
/ 28 июля 2010

Спасибо.

Я посмотрел на многие 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

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

0 голосов
/ 28 июля 2010

Прежде всего, я бы порекомендовал вам использовать ORM mapper - в настоящее время очень мало случаев, когда вам приходится выполнять ручное "отображение".Рекомендуется использовать имена полей вместо индексов при доступе к 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];
    }
}
...