简体   繁体   English

OdbcDataReader.GetBoolean()引发转换的奇怪问题不是布尔列的有效异常

[英]weird problem with OdbcDataReader.GetBoolean() throwing cast is not valid exception for bool column

Ok, this one is driving me completely crazy. 好的,这让我完全疯了。 I have a table in a PostgreSQL database and I'm trying to get the value a boolean column for a specific record with OdbcDataReader.GetBoolean(int col). 我在PostgreSQL数据库中有一个表,并且正在尝试使用OdbcDataReader.GetBoolean(int col)为特定记录获取布尔列的值。

The problem is that GetBoolean() keeps throwing a cast is not valid exception even though the same code worked just several days ago. 问题在于,即使同一代码几天前才起作用,GetBoolean()仍会抛出强制转换无效的异常。 What's even weirder is the same code works fine in another form. 甚至更奇怪的是,同一代码在另一种形式下也可以正常工作。

The only change made from the previous working version of my application was adding a column to the table. 对我的应用程序的先前工作版本所做的唯一更改是在表中添加了一个列。 That said, the index of the column that I need hasn't changed. 就是说,我需要的列的索引没有改变。 Oh yeah, getting the value with GetValue() and then calling GetType() on the result returns System.String and the true/false values get translated to 1/0. 哦,是的,使用GetValue()获取值,然后在结果上调用GetType()会返回System.String,并且true / false值将转换为1/0。

I'm all out of ideas. 我全都没主意了。

While I still have no idea what is causing this exception, I've managed to come up with code that works (not actual code from my app): 虽然我仍然不知道是什么导致了此异常,但是我设法提出了可以运行的代码(不是我应用程序中的实际代码):

val1 = reader.GetInt32(0);
val2 = reader.GetBoolean(4);
val3 = reader.GetBoolean(8);

This, however, does not: 但是,这不会:

val3 = reader.GetBoolean(8);
val1 = reader.GetInt32(0); // causes invalid cast exception
val2 = reader.GetBoolean(4);

Apparently, the column order has something to do with it. 显然,列顺序与此有关。

I don't think passing a System.String to GetBoolean() is going to work for you - as you can see from your exception you're getting an InvalidCastException, which means that internally somewhere it's trying to do something like this: 我认为将System.String传递给GetBoolean()不会为您工作-正如您从异常中看到的那样,您收到的是InvalidCastException,这意味着在内部某个地方它正在尝试执行以下操作:

string s = "true";
bool b = (bool)s;

That clearly won't work. 那显然是行不通的。

If you can see that ODBC is passing you back a System.String then you want to use either Convert.ToBoolean(), bool.TryParse(), or bool.Parse, depending on what exactly fits best with the rest of your code. 如果您看到ODBC正在将您传递回System.String,则您想使用Convert.ToBoolean(),bool.TryParse()或bool.Parse,具体取决于最适合其余代码的地方。

As to why it WAS working and now isn't - has someone else changed the underlying data type on the database field to a character-based type? 至于为什么它可以正常工作,现在却不起作用,是否有人将数据库字段上的基础数据类型更改为基于字符的类型?

This pattern is what we use to get boolean data out of an OdbcDataReader: 这种模式是我们用来从OdbcDataReader中获取布尔数据的方式:

data.Gender = reader["Gender"] == DBNull.Value ? 
    false : Convert.ToBoolean(reader["Gender"]);

Laborious, yes. 费力,是的。 But it works well for us. 但这对我们很好。 The underlying database for this code is Access ("yes/no" field type) or MS SQL Server ("bit" field type). 此代码的基础数据库是Access(“是/否”字段类型)或MS SQL Server(“ bit”字段类型)。

I ran into the same issue, it was actually due to an invalid cast I had in the SP I was calling... 我遇到了同样的问题,这实际上是由于我正在调用的SP中存在无效的强制转换造成的。

IN the Stored Proc 在存储过程中

declare @colA INT -- should have been a float!!!
set @colA = select someValue from someTable

select @someVar, someColumn
from someOtherTable

 //the line below works, even though it should have the SQL datatype is FLOAT
 _someVar = reader[2] != DBNull.Value ? reader.GetDouble[2] : 0;
  //the following line blows up w/invalid cast exception, even though it is correct
 _someColumn = reader[3] != DBNull.Value ? reader.GetBoolean[3] : false;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM