Estou usando um SQLdatareader para criar POCOs a partir de um banco de dados. O código funciona, exceto quando encontra um valor nulo no banco de dados. Por exemplo, se a coluna Nome no banco de dados contiver um valor nulo, uma exceção será lançada.
employee.FirstName = sqlreader.GetString(indexFirstName);
Qual é a melhor maneira de lidar com valores nulos nessa situação?
c#
sqldatareader
DenaliHardtail
fonte
fonte
int colIndex = reader.GetOrdinal(fieldname);
e sobrecarregar facilmente aSafeGetString
função de @ marc_s .Você deve usar o
as
operador combinado com o??
operador para valores padrão. Os tipos de valor precisarão ser lidos como anuláveis e receber um padrão.O
as
operador lida com a transmissão, incluindo a verificação de DBNull.fonte
sqlreader[indexAge] as string ?? ""
, sempre receberá""
. Considere se você realmente deseja(int?)sqlreader[indexAge] ?? defaultValue
, portanto, se o seu SQL mudar, você obterá exceções em vez de valores ruins. @ Stevo3000: o padrão (int) é 0, não -1. @ Chris: Verifique se você está usando o que você realmente deseja.Para uma string, você pode simplesmente converter a versão do objeto (acessada usando o operador array) e terminar com uma string nula para valores nulos:
ou
Para números inteiros, se você converter para um int nulo, poderá usar GetValueOrDefault ()
ou o operador de coalescência nula (
??
).fonte
null
mas sim um objeto DBNull. A diferença entre as duas instruções é que a primeira falhará se não for uma sequência, enquanto a segunda retornará nulo se não for uma sequência.IsDbNull(int)
geralmente é muito mais lento do que usar métodos comoGetSqlDateTime
e compararDBNull.Value
. Experimente estes métodos de extensão paraSqlDataReader
.Use-os assim:
fonte
Uma maneira de fazer isso é procurar nulos db:
fonte
reader.IsDbNull(ColumnIndex)
funciona como muitas respostas diz.E quero mencionar que, se você trabalha com nomes de colunas, apenas comparar tipos pode ser mais confortável.
fonte
Acho que não há um valor de coluna NULL , quando as linhas são retornadas em um datareader usando o nome da coluna.
Se você fizer
datareader["columnName"].ToString();
isso, sempre fornecerá um valor que pode ser uma sequência vazia (String.Empty
se você precisar comparar).Eu usaria o seguinte e não me preocuparia muito:
fonte
Esta solução é menos dependente do fornecedor e funciona com um SQL, OleDB e MySQL Reader:
fonte
O que costumo fazer é substituir os valores nulos na instrução SELECT por algo apropriado.
Aqui substituo todo nulo por uma sequência em branco. Seu código não irá gerar erros nesse caso.
fonte
Você pode escrever uma função genérica para verificar nulo e incluir o valor padrão quando for nulo. Chame isso ao ler Datareader
Ao ler o Datareader, use
fonte
Verifique
sqlreader.IsDBNull(indexFirstName)
antes de tentar lê-lo.fonte
Ao influenciar na resposta de getpsyched , criei um método genérico que verifica o valor da coluna pelo nome
Uso:
fonte
sobre como criar métodos auxiliares
For String
Uso
Para Int
Uso
Para data
Uso
Nota: para DateTime, declare varialbe como
fonte
Como complemento à resposta de marc_s, você pode usar um método de extensão mais genérico para obter valores do SqlDataReader:
fonte
Eu acho que você gostaria de usar:
fonte
Usamos uma série de métodos estáticos para extrair todos os valores de nossos leitores de dados. Então, neste caso, estaríamos chamando
DBUtils.GetString(sqlreader(indexFirstName))
O benefício de criar métodos estáticos / compartilhados é que você não precisa fazer as mesmas verificações repetidas vezes ...O (s) método (s) estático (s) conteria código para verificar se há nulos (consulte outras respostas nesta página).
fonte
Você pode usar o operador condicional:
fonte
Há muitas respostas aqui com informações úteis (e algumas informações erradas) espalhadas, eu gostaria de reunir tudo.
A resposta curta para a pergunta é verificar o DBNull - quase todo mundo concorda com esse bit :)
Em vez de usar um método auxiliar para ler valores anuláveis por tipo de dados SQL, um método genérico nos permite abordar isso com muito menos código. No entanto, você não pode ter um único método genérico para os tipos de valor anulável e de referência. Isso é discutido detalhadamente no tipo Nullable como um parâmetro genérico possível. e restrição de tipo genérico C # para tudo que pode ser anulado .
Portanto, seguindo as respostas de @ZXX e @getpsyched, terminamos com dois métodos para obter valores anuláveis e adicionei um terceiro para valores não nulos (ele completa o conjunto com base na nomeação de métodos).
Eu geralmente uso nomes de colunas, altere-os se você usar índices de colunas. Com base nesses nomes de método, posso dizer se estou esperando que os dados sejam anuláveis ou não, o que é bastante útil quando se olha o código escrito há muito tempo.
Dicas;
Por fim, ao testar os métodos acima em todos os tipos de dados do SQL Server, descobri que você não pode obter diretamente um char [] de um SqlDataReader; se você quiser um char [], precisará obter uma string e usar ToCharArray ().
fonte
Estou usando o código listado abaixo para manipular células nulas em uma planilha do Excel que é lida em uma tabela de dados.
fonte
fonte
e / ou usar operador ternário com atribuição:
substitua o valor padrão (quando nulo) conforme apropriado para cada tipo de propriedade ...
fonte
Esse método depende do indexFirstName, que deve ser a coluna ordinal com base em zero.
Se você não conhece o índice da coluna, mas não deseja verificar um nome, pode usar este método de extensão:
E use o método como este:
fonte
Pergunta antiga, mas talvez alguém ainda precise de uma resposta
na verdade, eu trabalhei em torno desta questão assim
Para int:
o mesmo para a string, basta retornar "" em vez de 0, pois "" é uma string vazia
então você pode usá-lo como
e
muito flexível para que você possa inserir qualquer consulta para ler qualquer coluna e ela nunca retornará com erro
fonte
Aqui está a classe auxiliar que outras pessoas podem usar se precisarem, com base na resposta @marc_s:
fonte
O Convert lida com DbNull de maneira sensata.
fonte
você já pode verificar isso também
fonte
SqlDataReader