我写了一个通用方法来从数据库中检索单个值(MSSQL Server)。
我遇到了一个需要从DB获取Boolean
值的情况。
正如您在下面的代码中看到的那样,Object
本地字段(IsExist
)会得到结果。
当DB中的值为False GenericScalar()
时,方法返回False(应该如此)
并且条件:if (IsExist == null)
中的GetWanLineDisconnectionData()
为真且返回块正在执行,即使IsExist为False且不为null。
为什么?
我该如何克服这个问题?
private void GetWanLineDisconnectionData()
{
string q = "SELECT WanLineDiscconection FROM AdditionalProjectsData WHERE SpCall= " + "'" + spCall + "'";
object IsExist = Orange.ProjectManagment.DAL.Database.GenericScalar<object>(q);
if (IsExist == null) {
return;
}
if (bool.Parse(IsExist) == true) {
RadWanDiscYes.Checked = true;
} else {
RadWanDiscNo.Checked = true;
}
}
数据库方法:
public static T GenericScalar<T>(string query)
{
OleDbConnection connection = new OleDbConnection(sqlConnString);
connection.Open();
OleDbCommand cmd = new OleDbCommand(query, connection);
try
{
var result = cmd.ExecuteScalar();
if (result == null)
{
return default(T);
}
else
{
return (T)result;
}
}
catch (Exception ex)
{
throw ex;
}
finally
{
CloseConnection(ref connection);
}
}
修改
也许一些屏幕拍摄会更好地展示它:
(请注意:GetWanLineDisconnectionData()
是用VB.NET编写的,而GenericScalar()
是用C#编写的,在解决方案中的另一个项目中):
答案 0 :(得分:1)
foo
中的变量object foo = false
绝对不是null
,因此标题中的前提不正确。
ExecuteScalar()
会返回null
。在这种情况下,方法GenericScalar()
会返回default(T)
,object
将为null
。
如何解决这个问题取决于您的数据是什么样的。您可能希望以可空的int或int?
而不是object
来表示结果:
var exists = Orange.ProjectManagment.DAL.Database.GenericScalar<int?>(q);
RadWanDiscYes.Checked = exists.GetValueOrDefault() > 0;
请参阅How does GetValueOrDefault work?,What is the default value of the nullable type "int?" (including question mark)?。
除此之外:你通常也不想为数据库查询编写方便的包装器,因为你不能很好地重新发明轮子,打开你的应用程序进行SQL注入。话虽如此,在该方法中出现了更多错误,包括但不限于不处理数据库连接并在没有堆栈跟踪的情况下重新抛出异常。
答案 1 :(得分:0)
混合编译 -time和运行时信息。虽然GenericScalar<object>(q)
是在编译时存在的信息,但在 compile -time从ExecuteScalar
返回的类型仅为object
。您希望它属于boolean
类型,对于您的特定情况可能适用也可能不适用。但是这与编译器无关。
简而言之,这意味着T
实际上是object
,而不是您对数据库的期望。正如CodeCaster已经提到的那样,object
的默认值只是null
。
我建议使用GenericScalar<bool>
而不是GenericScalar<object>
,因为您似乎知道您的查询实际返回的内容 - 在您的情况下是bool
。然后,default(T)
评估为false
,而不评估为null
。