Невозможно привести объект типа ' System.DBNull 'to type' система.Строка`
Я получил выше ошибку в моем приложении. Вот исходный код
public string GetCustomerNumber(Guid id)
{
string accountNumber =
(string)DBSqlHelperFactory.ExecuteScalar(connectionStringSplendidmyApp,
CommandType.StoredProcedure,
"GetCustomerNumber",
new SqlParameter("@id", id));
return accountNumber.ToString();
}
Я заменить
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();
}
}
есть ли лучший способ обойти это?
11 ответов:
можно использовать более короткую форму:
return (accountNumber == DBNull.Value) ? string.Empty : accountNumber.ToString()EDIT: не обращал внимания на ExecuteScalar. Он действительно возвращает null, если поле отсутствует в возвращаемом результате. Так что используйте вместо этого:
return (accountNumber == null) ? string.Empty : accountNumber.ToString()
С помощью простой общей функции вы можете сделать это очень легко. Просто сделайте это:
return ConvertFromDBVal<string>(accountNumber);С помощью функции:
public static T ConvertFromDBVal<T>(object obj) { if (obj == null || obj == DBNull.Value) { return default(T); // returns the default value for the type } else { return (T)obj; } }
ExecuteScalar вернет
- null, если нет результирующего набора
- в противном случае первый столбец первой строки результирующего набора, который может быть DBNull.
Если вы знаете, что первый столбец результирующего набора является строкой, то для покрытия всех баз вам нужно проверить как null, так и DBNull. Что-то вроде:
object accountNumber = ...ExecuteScalar(...); return (accountNumber == null) ? String.Empty : accountNumber.ToString();приведенный выше код опирается на то, что DBNull.ToString возвращает пустую строку.
Если accountNumber был другим типом (скажем integer), тогда вам нужно было бы быть более явным:
object accountNumber = ...ExecuteScalar(...); return (accountNumber == null || Convert.IsDBNull(accountNumber) ? (int) accountNumber : 0;Если вы точно знаете, что ваш результирующий набор всегда будет иметь хотя бы одну строку (например, выберите COUNT(*)...), то вы можете пропустить проверку на null.
в вашем случае сообщение об ошибке "не удается привести объект типа ‘System.DBNull 'to type' система.Строка '" указывает, что первый столбец результирующего набора является значением DBNUll. Это приведение к строке на первом линия:
string accountNumber = (string) ... ExecuteScalar(...);комментарий Marc_s, что вам не нужно проверять DBNull.Значение неверно.
есть другой способ обойти эту проблему. Как насчет изменения процедуры вашего магазина? используя функцию isnull (your field, "") sql , вы можете вернуть пустую строку, если возвращаемое значение равно null.
тогда у вас есть чистый код в качестве оригинальной версии.
это общий метод, который я использую для преобразования любого объекта, который может быть DBNull.Значение:
public static T ConvertDBNull<T>(object value, Func<object, T> conversionFunction) { return conversionFunction(value == DBNull.Value ? null : value); }использование:
var result = command.ExecuteScalar(); return result.ConvertDBNull(Convert.ToInt32);короче:
return command .ExecuteScalar() .ConvertDBNull(Convert.ToInt32);
Я полагаю, вы можете сделать это так:
string accountNumber = DBSqlHelperFactory.ExecuteScalar(...) as string;Если accountNumber равен null, это означает, что это был DBNull не string :)
строку.Concat преобразует значения DBNull и null в пустую строку.
public string GetCustomerNumber(Guid id) { object accountNumber = (object)DBSqlHelperFactory.ExecuteScalar(connectionStringSplendidCRM, CommandType.StoredProcedure, "spx_GetCustomerNumber", new SqlParameter("@id", id)); return String.Concat(accountNumber); }однако, я думаю, что вы теряете что-то на понятности кода
Так как я получил экземпляр, который не является null и если я по сравнению с DBNULL я получил
Operator '==' cannot be applied to operands of type 'string' and 'system.dbnull'exeption, и если я попытался изменить для сравнения с NULL, это просто не сработало ( поскольку DBNull является объектом), даже это принятый ответ.Я решил просто использовать ключевое слово 'is'. Так что результат очень читабельный:
data = (item is DBNull) ? String.Empty : item
Я использую расширение, чтобы устранить эту проблему для меня, которая может или не может быть то, что вы после.
это звучит так:
public static class Extensions { public String TrimString(this object item) { return String.Format("{0}", item).Trim(); } }Примечание:
Это расширение не возвращение
nullзначения! Если элементnullили DBNull.Значение, он вернет пустую строку.использование:
public string GetCustomerNumber(Guid id) { var obj = DBSqlHelperFactory.ExecuteScalar( connectionStringSplendidmyApp, CommandType.StoredProcedure, "GetCustomerNumber", new SqlParameter("@id", id) ); return obj.TrimString(); }
Comments