C# 将 tiny int 转换为 int 时出错

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12819408/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 00:32:55  来源:igfitidea点击:

Error casting tiny int to int

c#sql-servercasting

提问by David M?rtensson

This error looks like it was caused by installing framework 4.5 on the server even though the project is still targeted to 4.0.

此错误似乎是由在服务器上安装框架 4.5 引起的,即使该项目仍以 4.0 为目标。

4.5 replaces the CLR and it looks like it has changes in unboxing an object of type tinyint to a int. This was working in 4.0 but not after installing 4.5.

4.5 替换了 CLR,看起来它在将 tinyint 类型的对象拆箱为 int 方面发生了变化。这在 4.0 中有效,但在安装 4.5 后无效。

============================================

============================================

Please read the whole question before answering, most current answers do not answer the question I am asking.

请在回答之前阅读整个问题,大多数当前的答案都没有回答我要问的问题。

We today got an error in a cast from a tinyint in sql to an int using

我们今天在从 sql 中的 tinyint 到 int 的转换中遇到了一个错误,使用

Daterow datarow = GetOneDatarow(connection,
                         "SELECT tinyintcolumn FROM table1 WHERE id = 4");
int i = (int)datarow["tinyintcolumn"];

This is old code that has been in the product for several years without any changes and it has been working up until yesterday. (And it is not the exact code, just enough to show the context)

这是已在产品中使用多年且没有任何更改的旧代码,并且一直运行到昨天。(这不是确切的代码,足以显示上下文)

=== UPDATE

=== 更新

The exact error message was: "The specified cast is not valid!" and the last line

确切的错误消息是:“指定的演员表无效!” 和最后一行

int i = (int)datarow["tinyintcolumn"];

is the exact row from our code casting the error with only variable names and column name changed.

是我们的代码中的确切行,仅更改了变量名和列名。

And the database column was tinyint with default value 0, no indexes or other constraints.

数据库列是 tinyint,默认值为 0,没有索引或其他约束。

=== End update

=== 结束更新

=== UPDATE 2

=== 更新 2

Henk Holterman in his response informed me that FW 4.5 replaces the CLR of 4.0 even for projects compiled specifically for 4.0 and this could remotely change existing 4.0 behaviour just like this.

Henk Holterman 在他的回复中告诉我,即使是专门为 4.0 编译的项目,FW 4.5 也替换了 4.0 的 CLR,这可以像这样远程改变现有的 4.0 行为。

I will keep this open a while more but his answer is the most promising so far :D === End

我会让这个开放一段时间,但他的答案是迄今为止最有希望的 :D === 结束

We changed from framework 3.5 to 4.0 a few weeks ago but it was only yesterday afternoon after a recompile that this happened, yesterday morning the same code (even after recompile) worked like clockwork.

几周前我们将框架 3.5 更改为 4.0,但直到昨天下午重新编译后才发生这种情况,昨天早上相同的代码(即使在重新编译后)也像时钟一样工作。

Do anyone have any idea on why this was working before and is not working now?

有没有人知道为什么这以前有效而现在无效?

Has Microsoft made any under the hood changes that removed an implicit conversion or has it worked by pure magic before?

Microsoft 是否进行了任何隐藏的更改以消除隐式转换,或者它之前是否通过纯魔法起作用?

We solved it by changing the database column to int, but I am still curious on what might have caused it to fail right now.

我们通过将数据库列更改为 int 来解决它,但我仍然很好奇可能导致它现在失败的原因。

=== UPDATE 3

=== 更新 3

Just to complete this.

就是为了完成这个。

I found the change between frameworks. In an update Microsoft changed how boxing and unboxing is done. This caused the implicit cast from byte to int that older FW did to fail when the byte was boxed, as it is in a datatable.

我发现了框架之间的变化。在更新中,微软改变了装箱和拆箱的方式。这导致当字节被装箱时,旧固件从字节到 int 的隐式转换失败,因为它在数据表中。

An unboxed byte will will in 4.5 be implicitly cast to an int, but a boxed byte is an generic object which cannot be implicitly cast.

未装箱的字节将在 4.5 中隐式转换为 int,但装箱的字节是不能隐式转换的通用对象。

Not, this was changed in 3.5 SP1 so our FW 4.0 should also have failed, unless the update to SP1 was not in the 4.0 update. This has yet to be answered :)

不是,这在 3.5 SP1 中已更改,因此我们的 FW 4.0 也应该失败,除非 SP1 的更新不在 4.0 更新中。这还有待回答:)

Here is the ticket from MS on this ;) https://connect.microsoft.com/VisualStudio/feedback/details/766887/casting-tinyint-from-sql-datarow-to-int-no-longer-possible

这是 MS 的票;) https://connect.microsoft.com/VisualStudio/feedback/details/766887/casting-tinyint-from-sql-datarow-to-int-no-longer-possible

采纳答案by Henk Holterman

It should never have worked. Which makes it likely that something was fixed in the framework.

它不应该奏效。这使得框架中可能修复了某些内容。

The problem in C#:

C#中的问题:

byte b = 3;       // TinyInt is a Byte
object o = b;     // DataRow[i] is an object
int i = (int)o;   // invalid cast

The fix:

修复:

int i = (byte)datarow["tinyintcolumn"];


And from the comment trail below:

从下面的评论线索:

We have installed it, but this project is not compiled towards 4.5, only to 4.0, ... could that be the case?

我们已经安装了它,但是这个项目没有编译到 4.5,只编译到 4.0,... 是这样吗?

Yes, framework 4.5 replaces parts of 4.0.

是的,框架 4.5 替换了 4.0 的部分内容。

回答by Rob Hardy

a TinyInt type will by default return a byte type which itself is castable to an int, but the db's TinyInt type is not, so try this:

默认情况下,TinyInt 类型将返回一个字节类型,它本身可以转换为 int,但数据库的 TinyInt 类型不是,所以试试这个:

(int)(byte)datarow["tinyintcolumn"];

回答by Nickon

Because tinyintis a Bytetype. Here's a list: LIST

因为tinyint是一个Byte类型。这是一个列表:LIST

You need to convert byte arrayto int. Solution here: SOLUTION

您需要转换byte arrayint. 解决方案在这里:解决方案

回答by Fredrik

I believe the size of SQL's tinyint is 1 byte (8 bits) so try casting it to a 'byte' instead of casting it to an 'int' (which is 32 bits). But I have not tried this since I don't use tinyint in my database.

我相信 SQL 的 tinyint 的大小是 1 字节(8 位),所以尝试将其转换为 'byte' 而不是将其转换为 'int'(32 位)。但是我没有尝试过这个,因为我没有在我的数据库中使用 tinyint。

byte i = (byte)datarow["tinyintcolumn"];

Also, if your column in the database tinyintcolumn is nullable, you also need to take that into account when you cast the value.

此外,如果您在数据库 tinyintcolumn 中的列可以为空,则在转换值时也需要考虑到这一点。

回答by Repeat Spacer

To make the answer usable with other connection libraries I share this. I'm using MariaDb and MySql connector/Net so selected answer did not work for me directly. So first you have to find out the C# datatype of returned sql tinyint field.

为了使答案可用于其他连接库,我分享了这个。我正在使用 MariaDb 和 MySql 连接器/网络,所以选择的答案对我没有直接作用。所以首先你必须找出返回的 sql tinyint 字段的 C# 数据类型。

Here is example:

这是示例:

I'm using MySqlHelper.ExecuteDataset() and executing query to fetch tinyint(4) column:

我正在使用 MySqlHelper.ExecuteDataset() 并执行查询以获取 tinyint(4) 列:

SELECT tinyintcolumn FROM datatable WHERE ...

I was getting the "The specified cast is not valid!" exception even if i used cast function in SQL query:

我收到“指定的演员表无效!” 即使我在 SQL 查询中使用了强制转换函数,也会出现异常:

SELECT CAST(tinyintcolumn AS int) ...

I was first trying all suggested here and elsewhere, but finally what worked is finding out what is the type of field in c#:

我首先尝试了这里和其他地方的所有建议,但最终有效的是找出 c# 中的字段类型:

DataTable datatable MySqlHelper.ExecuteDataset(connString, sql).Tables[0];
DataRow datarow = datatable .Rows[0];
Type datatype = datarow.ItemArray[0].GetType();

Result: System.SByte! So for me it's fine to use one of this:

结果:System.SByte!所以对我来说,可以使用其中之一:

SByte sbTinyint = datarow.Field<SByte>(0);
SByte sbTinyint2 = (SByte)datarow.ItemArray[0];
int iTinyint = (int)datarow.Field<SByte>(0);
int iTinyint2 = (int)(SByte)datarow.ItemArray[0];