Nullable Types e Base de Dados


Sinceramente imaginei que as coisas seriam mais fáceis quando se trabalha com Nullable Types e base de dados. Hoje estou fazendo alguns testes para entender o comportamento desta nova feature do .NET Framework 2.0. Independente de qualquer coisa que venho a dizer, é de qualquer forma bem legal trabalhar com eles, mas infelizmente quando fui testar a principal utilização do mesmo ao meu ver, que é em conjunto com uma base de dados, fui surpreendido! Explico:

Imaginei eu que poderia fazer algo como:

Dim dr As SqlDataReader = cmd.ExecuteReader()
‘…
Dim dataCompra As Nullable(Of DateTime) = dr.GetDateTime(0)
‘…
If Not dataCompra.HasValue Then MessageBox.Show(“Valor Nulo.”)

Isso seria o ideal ao meu ver, mas quando tentei rodar, me deparei com a seguinte Exception (para minha decepção): System.Data.SqlTypes.SqlNullValueException: Data is Null. This method or property cannot be called on Null values.

Se dermos uma procurada dentro do Reflector pelo método GetDateTime do SqlDataReader, chegamos à função chamada ThrowIfNull(), que atira a exception acima, caso o campo da base de dados que estamos tentando acessar for nulo:

Private Sub ThrowIfNull()
      If Me.IsNull Then
            Throw New SqlNullValueException
      End If
End Sub

Depois disso, resolvi procurar algo no Google a respeito e me deparei com estes dois posts que abordam exatamente isso, ou seja, pelo que entendi, não podemos acessar diretamente os valores nulos da base de dados e atribuirmos aos CLR Nullables Types, sendo necessário uma verificação antes, ficando o código dessa forma:

Dim dr As SqlDataReader = cmd.ExecuteReader()
‘…
Dim dataCompra As Nullable(Of DateTime)
If (Not dr.IsDBNull(0)) Then dataCompra = dr.GetDateTime(0)
‘…
If Not dataCompra.HasValue Then MessageBox.Show(“Valor Nulo.”)

E para piorar, nem o “operador” IIf (no caso do VB.NET) não pode ser utilizado por problemas já reportados anteriormente aqui. A questão é que, se eu tranformar a minha variável dataCompra em um tipo SqlDateTime (tipo que está contido dentro do Namespace System.Data.SqlTypes), eu consigo chegar ao resultado esperado sem problemas:

Dim dr As SqlDataReader = cmd.ExecuteReader()
Dim dataCompra As SqlTypes.SqlDateTime = dr.GetSqlDateTime(0)
If dataCompra.IsNull Then MessageBox.Show(“Valor Nulo.”)

O problema que vejo nisso, é quando vamos atribuir o result-set em um objeto de negócio que temos – quais sempre criamos as suas propriedades com tipos do CLR e não tipos específicos de uma base de dados qualquer – irá obrigar-nos antes de atribuir o valor à mesma, verificar antes se é ou não nulo.

Anúncios

Deixe uma resposta

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s