无法转换类型为“System.DBNull”的对象 输入“System.String”
我在我的应用程序中收到上述错误。 原始代码
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();
}
}
是否有更好的方法解决这个问题?
I got the above error in my app. Here is the original code
public string GetCustomerNumber(Guid id)
{
string accountNumber =
(string)DBSqlHelperFactory.ExecuteScalar(connectionStringSplendidmyApp,
CommandType.StoredProcedure,
"GetCustomerNumber",
new SqlParameter("@id", id));
return accountNumber.ToString();
}
I replaced with
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();
}
}
Is there a better way around this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(13)
通过一个简单的通用函数,您可以使这变得非常容易。 只需这样做:
使用该函数:
With a simple generic function you can make this very easy. Just do this:
using the function:
可以使用更短的形式:
编辑:还没有注意
ExecuteScalar
。 如果返回结果中不存在该字段,它确实返回 null。 所以改用:A shorter form can be used:
EDIT: Haven't paid attention to
ExecuteScalar
. It does really return null if the field is absent in the return result. So use instead:ExecuteScalar 将返回
如果您知道结果集的第一列是字符串,那么要涵盖所有基础,您需要检查 null 和 DBNull。 类似于:
上面的代码依赖于 DBNull.ToString 返回空字符串的事实。
如果 accountNumber 是另一种类型(比如整数),那么您需要更明确:
如果您确定结果集始终至少有一行(例如 SELECT COUNT(*)...),那么您可以跳过对 null 的检查。
在您的情况下,错误消息“无法将类型为‘System.DBNull’的对象转换为类型为‘System.String`”表示结果集的第一列是 DBNUll 值。 这是来自第一行的字符串转换:
Marc_s 的评论说你不需要检查 DBNull.Value 是错误的。
ExecuteScalar will return
If you know that the first column of the resultset is a string, then to cover all bases you need to check for both null and DBNull. Something like:
The above code relies on the fact that DBNull.ToString returns an empty string.
If accountNumber was another type (say integer), then you'd need to be more explicit:
If you know for sure that your resultset will always have at least one row (e.g. SELECT COUNT(*)...), then you can skip the check for null.
In your case the error message "Unable to cast object of type ‘System.DBNull’ to type ‘System.String`" indicates that the first column of your result set is a DBNUll value. This is from the cast to string on the first line:
Marc_s's comment that you don't need to check for DBNull.Value is wrong.
您可以使用 C# 的空合并运算符
You can use C#'s null coalescing operator
这是我用来转换任何可能是 DBNull.Value 的对象的通用方法:
用法:
更短:
This is the generic method that I use to convert any object that might be a DBNull.Value:
usage:
shorter:
还有另一种方法可以解决此问题。 修改一下你的商店流程怎么样? 通过使用 ISNULL(your field, "") sql 函数,如果返回值为 null,则可以返回空字符串。
然后你就得到了原始版本的干净代码。
There is another way to workaround this issue. How about modify your store procedure? by using ISNULL(your field, "") sql function , you can return empty string if the return value is null.
Then you have your clean code as original version.
我想你可以这样做:
如果 accountNumber 为空,则意味着它是 DBNull 而不是字符串:)
I suppose you can do it like this:
If accountNumber is null it means it was DBNull not string :)
String.Concat 将 DBNull 和 null 值转换为空字符串。
然而,我认为你在代码的可理解性上失去了一些东西
String.Concat transforms DBNull and null values to an empty string.
However, I think you lose something on code understandability
由于我得到了一个不为 null 的实例,并且如果与 DBNULL 进行比较,我得到了
Operator '==' can not apply to operands of type 'string' and 'system.dbnull'
例外,如果我尝试更改为与 NULL 进行比较,它根本不起作用(因为 DBNull 是一个对象),即使这是公认的答案。
我决定简单地使用“is”关键字。
所以结果非常可读:
data = (item is DBNull) ? String.Empty:项目
Since I got an instance which isn't null and if I compared to DBNULL I got
Operator '==' cannot be applied to operands of type 'string' and 'system.dbnull'
exeption,and if I tried to change to compare to NULL, it simply didn't work ( since DBNull is an object) even that's the accepted answer.
I decided to simply use the 'is' keyword.
So the result is very readable:
data = (item is DBNull) ? String.Empty : item
使用更新的 C# 语法并考虑可空类型的更简洁的方法:
可以与数据读取器一起使用,如下所示:
A more concise approach using more recent C# syntax and also accounting for nullable types:
Can be used with a data reader as follows:
因为我自己也遇到了类似的错误,这是谷歌上的第一个点击。
如果您没有将可空属性配置为与您的数据库匹配,则可能会发生相同的错误。
如果您只需要快速& 丑陋的修复,你可以添加:
在模型类的开头禁用。
Since I just had a similar error myself and this is the first hit on google.
If you do not have your properties nullable configured to match your database, the same error can occur.
If you just need a quick & ugly fix, you can add:
at the start of your model class.
基于 @rein
给出的答案:
使用 as:
或者,如果您在异常方法中硬编码类类型:
ps 我还没有弄清楚如何在不牺牲代码长度的情况下使
generics
隐式。免费发表评论并提出改进建议完整示例:
只要表列名称与类的属性名称匹配,解决方案就有效。 并且可能不是生产级性能明智的,因此使用或修改需要您自担风险:)
based on answer from @rein
Given:
Use as:
or, if you hardcode class type in exception method:
p.s. I haven't figured yet how to make
generics
implicit without sacrificing code length.. fee free to comment and suggest improvementsFull example:
Solution will work for as long as table column names match property names of the class. And might not be production-grade performance wise, so use or modify at your own risk :)
将其转换为
Convert it Like