Maneira adequada para valores de banco de dados Unbox
Pergunta
Estou trabalhando com um banco de dados Oracle mais antigo e sinto que provavelmente há uma maneira melhor de unir os valores que recupero do banco de dados.
Atualmente, tenho uma classe estática cheia de diferentes métodos específicos de tipo:
public static int? Int(object o)
{
try
{
return (int?)Convert.ToInt32(o);
}
catch (Exception)
{
return null;
}
}
..e assim por diferentes tipos, mas sinto que deve haver uma maneira melhor? Se eu quiser unir um valor, faço algo parecido com ...
int i;
i = nvl.Int(dataRow["column"]); //In this instance, "column" is of a numeric database type
Pensei em usar uma classe genérica para lidar com todos os tipos diferentes, mas não consegui descobrir a melhor maneira de fazer isso.
Alguma ideia?
Solução
Acho que métodos auxiliares, como os seguintes seguintes, em seu cenário - o teste para o DBNULL é mais eficiente do que pegar uma exceção como no seu exemplo:
public static MyHelper
{
public static Nullable<T> ToNullable<T>(object value) where T : struct
{
if (value == null) return null;
if (Convert.IsDBNull(value)) return null;
return (T) value;
}
public static string ToString(object value)
{
if (value == null) return null;
if (Convert.IsDBNull(value)) return null;
return (string)value;
}
}
Isso funciona para a string e os tipos de valor primitivo usuais que você encontrará (int, decimal, duplo, bool, dateTime).
É um pouco diferente do seu exemplo, pois ele lança em vez de converter - mas pessoalmente eu prefiro isso. Ou seja, se a coluna do banco de dados for numérica (decimal), prefiro ser explícito se quisesse converter o valor para int, por exemplo:
int? myIntValue = (int?) MyHelper.ToNullable<decimal>(reader["MyNumericColumn"]);
Outras dicas
Você pode introduzir classes de modelos simples e mapear entre elas.
Por exemplo:
public class Customer
{
public Customer(DataRow row)
{
Name = row["Name"];
}
public Name { get; private set; }
}
Obviamente, para reduzir o código duplicado, você pode criar uma classe base para as classes de dados do modelo.
Dependendo do esforço que você deseja gastar, você pode usar um mapeador ORM Nibernate.