Maneira nula segura de obter valores de um idatarader
-
25-09-2019 - |
Pergunta
(LocalVariable) abc.string (nome) = (idatarader) dataReader.getString (0);
Esse valor de nome é proveniente do banco de dados. O que está acontecendo aqui é se esse valor de nome for nulo enquanto lê que está lançando uma exceção?
Estou fazendo um pouco de condição se aqui. Não quero escrever uma condição manual para verificar todas as minhas variáveis.
Estou fazendo algo assim agora ..
string abc = (Idatareader)datareader.GetValue(0);
if(abc = null)
//assiging null
else
assiging abc value
Existe algo como podemos escrever um método de extensão para isso? obrigado
Solução
Aqui estão alguns métodos de extensão que encerram bem todas as suas preocupações em recuperar valores fortemente digitados de um leitor de dados. Se o valor for dbnull, o padrão do tipo será retornado. No caso de string
que é uma classe, um null
será retornado. Se o campo fosse int
, então 0
seria devolvido. Além disso, se você está esperando um int?
, digamos de um campo int nullável, null
seria devolvido.
Uso específico para o caso de Kumar:
string abc = datareader.GetValueOrDefault<string>(0);
Uso geral
var name = GetValueOrDefault<string>(reader, "Name");
ou
var name = reader.GetValueOrDefault<string>("Name");
ou
var name = reader.GetValueOrDefault<string>(0);
Extensão
public static class NullSafeGetter
{
public static T GetValueOrDefault<T>(this IDataRecord row, string fieldName)
{
int ordinal = row.GetOrdinal(fieldName);
return row.GetValueOrDefault<T>(ordinal);
}
public static T GetValueOrDefault<T>(this IDataRecord row, int ordinal)
{
return (T)(row.IsDBNull(ordinal) ? default(T) : row.GetValue(ordinal));
}
}
a partir de http://skysanders.net/subtext/archive/2010/03/02/generic-nullsafe-idatarecord-field-getter.aspx
Outras dicas
Semelhante ao @Sky-Sanders Responder, mas menos rigoroso com as conversões:
public static T Get<T>(this IDataRecord row, string fieldName)
{
int ordinal = row.GetOrdinal(fieldName);
return row.Get<T>(ordinal);
}
public static T Get<T>(this IDataRecord row, int ordinal)
{
var value = row.IsDBNull(ordinal) ? default(T) : row.GetValue(ordinal);
return (T)Convert.ChangeType(value, typeof(T));
}
Minha solução é isso:
private static T GetValue<T>(object o) {
if (typeof(DBNull) != o.GetType()) {
return (T) o;
}
return default(T);
}
Quando, Status = GetValue<string>(currentDataRow["status"])
Combinando as principais soluções e sugestões, aqui está um C# 6 Expressão de seta versão com suporte para GetValue<T>
e GetValueOrDefault<T>
com parâmetros de valor padrão opcional.
public static class DataRecordExtensions {
/// <summary>
/// Generically extracts a field value by name from any IDataRecord as specified type. Will throw if DNE.
/// </summary>
public static T GetValue<T>(this IDataRecord row, string fieldName)
=> row.GetValue<T>(row.GetOrdinal(fieldName));
/// <summary>
/// Generically extracts a field value by ordinal from any IDataRecord as specified type. Will throw if DNE.
/// </summary>
public static T GetValue<T>(this IDataRecord row, int ordinal)
=> (T)row.GetValue(ordinal);
/// <summary>
/// Generically extracts a field value by name from any IDataRecord as specified type. Will return default generic types value if DNE.
/// </summary>
public static T GetValueOrDefault<T>(this IDataRecord row, string fieldName, T defaultValue = default(T))
=> row.GetValueOrDefault<T>(row.GetOrdinal(fieldName), defaultValue);
/// <summary>
/// Generically extracts a field value by ordinal from any IDataRecord as specified type. Will return default generic types value if DNE.
/// </summary>
public static T GetValueOrDefault<T>(this IDataRecord row, int ordinal, T defaultValue = default(T))
=> (T)(row.IsDBNull(ordinal) ? defaultValue : row.GetValue(ordinal));
}
Eu usaria algo assim:
string abc = (IDataReader)datareader.GetValue(0) ?? "Default";