Recebi o erro acima em meu aplicativo. Aqui está o código original
public string GetCustomerNumber(Guid id)
{
string accountNumber =
(string)DBSqlHelperFactory.ExecuteScalar(connectionStringSplendidmyApp,
CommandType.StoredProcedure,
"GetCustomerNumber",
new SqlParameter("@id", id));
return accountNumber.ToString();
}
Eu substituí com
public string GetCustomerNumber(Guid id)
{
object accountNumber =
(object)DBSqlHelperFactory.ExecuteScalar(connectionStringSplendidCRM,
CommandType.StoredProcedure,
"spx_GetCustomerNumber",
new SqlParameter("@id", id));
if (accountNumber is System.DBNull)
{
return string.Empty;
}
else
{
return accountNumber.ToString();
}
}
Existe uma maneira melhor de contornar isso?
Respostas:
Uma forma mais curta pode ser usada:
EDIT: Não prestei atenção ao ExecuteScalar. Ele realmente retorna nulo se o campo estiver ausente no resultado de retorno. Portanto, use:
fonte
null
, se a linha selecionada tiverNULL
nessa coluna, o valor de retorno éSystem.DBNull
.Com uma função genérica simples, você pode tornar isso muito fácil. Basta fazer isso:
usando a função:
fonte
ExecuteScalar irá retornar
Se você sabe que a primeira coluna do conjunto de resultados é uma string, para cobrir todas as bases, você precisa verificar se há nulo e DBNull. Algo como:
O código acima se baseia no fato de que DBNull.ToString retorna uma string vazia.
Se accountNumber fosse outro tipo (digamos, inteiro), você precisaria ser mais explícito:
Se você tiver certeza de que seu conjunto de resultados sempre terá pelo menos uma linha (por exemplo, SELECT COUNT (*) ...), você pode ignorar a verificação de nulo.
No seu caso, a mensagem de erro "Não foi possível lançar o objeto do tipo 'System.DBNull' para o tipo 'System.String`" indica que a primeira coluna do conjunto de resultados é um valor DBNUll. Isso é do elenco para a string na primeira linha:
O comentário de Marc_s de que você não precisa verificar DBNull.Value está errado.
fonte
Você pode usar o operador de coalescência nula do C #
fonte
Existe outra maneira de contornar esse problema. Que tal modificar seu procedimento de loja? usando ISNULL (seu campo, "") a função sql, você pode retornar uma string vazia se o valor de retorno for nulo.
Então você tem seu código limpo como versão original.
fonte
Este é o método genérico que uso para converter qualquer objeto que possa ser um DBNull.Value:
uso:
mais curta:
fonte
Suponho que você pode fazer assim:
Se accountNumber for null, significa que não era DBNull string :)
fonte
return (accountNumber as string) ?? string.Empty;
, com accountNumber ainda sendo umobject
. Se você preferir manter sua chamada de banco de dados em sua própria linha.String.Concat transforma os valores DBNull e nulos em uma string vazia.
No entanto, acho que você perde algo na compreensão do código
fonte
return "" + accountNumber;
?Já que eu obtive uma instância que não é nula e se eu comparei com DBNULL eu tive exceção
Operator '==' cannot be applied to operands of type 'string' and 'system.dbnull'
, e se eu tentei mudar para comparar com NULL, simplesmente não funcionou (já que DBNull é um objeto) mesmo essa resposta aceita.Decidi simplesmente usar a palavra-chave 'é'. Portanto, o resultado é muito legível:
data = (item is DBNull) ? String.Empty : item
fonte
Eu uso uma extensão para eliminar esse problema para mim, que pode ou não ser o que você está procurando.
É assim:
Nota:
Esta extensão não retorna
null
valores! Se o item fornull
ou DBNull.Value , ele retornará uma String vazia.Uso:
fonte
Converta como
fonte