【问题标题】:"Specified cast is not valid" when a null value is returned as Nullable<int>当 null 值返回为 Nullable<int> 时,“指定的强制转换无效”
【发布时间】:2012-10-08 11:43:29
【问题描述】:

在我的 SQL 数据库中,我有以下视图:

CREATE VIEW MyView AS
(SELECT ChangeType FROM MyTable) UNION ALL
(SELECT NULL AS ChangeType FROM MyTable)

其中ChangeType 的类型为TINYINT。然后在我的 C# 代码中,我有以下类:

[Table(Name = "MyView")]
public class MyView
{
    [Column]
    public Nullable<int> ChangeType;
}

具体用法如下:

var table = dataContext.GetTable<MyView>();
var elements = table.ToArray();

当这段代码运行时,我得到以下异常:

[InvalidCastException: Specified cast is not valid.]
System.Data.SqlClient.SqlBuffer.get_Int32() +6393860
Read_MyView(ObjectMaterializer`1 ) +3404
System.Data.Linq.SqlClient.ObjectReader`2.MoveNext() +42
System.Linq.Buffer`1..ctor(IEnumerable`1 source) +488
System.Linq.Enumerable.ToArray(IEnumerable`1 source) +104
MyCodeHere

如果我将UNION 的第二部分更改如下:

(SELECT CONVERT(INT,NULL) AS ChangeType FROM MyTable)

同样的代码运行良好。

为什么那里的“演员表无效”?为什么TINYINT 不能代替int 被读取?

【问题讨论】:

  • 见这篇文章:stackoverflow.com/questions/425389/…> TinyInt 映射到 CLR 中的 Byte
  • 看这篇文章:stackoverflow.com/questions/425389/…> TinyInt 映射到 CLR 中的 Byte

标签: c# .net sql-server linq-to-sql


【解决方案1】:

为什么不只读取 TINYINT 来代替 int?

因为TINYINT 映射到shortsbyte

编辑:Looked it up,它是一个无符号字节,所以使用byte

[Column]
public Nullable<byte> ChangeType; 

您的堆栈跟踪显示 Linq2Sql 映射器调用 .get_Int32()。假设这类似于SqlDataReader.GetInt32(),那么这意味着它将尝试读取 32 位值,不应用任何转换。

【讨论】:

  • 反正tinyint适合int就好了,为什么会出现异常?
  • 是的,您可以(隐式)将byte 值转换为int。但是您不能在字节大小的列上调用GetInt32()。更严格的规则。
  • 太好了,您能否在答案中包含最后一点?
【解决方案2】:

尝试使用

[Column]
    public Nullable<Int32> ChangeType; //for int type
    public Nullable<Int16> ChangeType; //for smallint type

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-06-30
    • 2014-05-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多