如何修复 exception:Unable 以将类型 'System.DBNull' 的对象转换为类型 'System.Byte[]'

How to fix exception:Unable to cast object of type 'System.DBNull' to type 'System.Byte[]'

我有一个名为 tblStaff 的 table,其中名为 staffImage 的列具有图像数据类型,允许存储 Null.If 用户提供他的照片,然后此列将图像存储为二进制数据,如果他不提供他的图像然后它将存储 Null value.If 此列具有 null 值然后资源文件夹中的图像应显示在 pictureBox1 中,如果此列具有二进制数据则图像作为二进制数据存储在此列中应显示在 pictureBox1.

CREATE TABLE tblStaff
(
    staffId int not null identity Primary Key,
    staffName varchar(50) not null,
    staffUserName varchar(25) not null,
    staffPassword varchar(30) not null,
    staffPhone varchar(15) not null,
    staffRole int not null,
    staffStatus tinyint not null,
    **staffImage image**
)

    ALTER PROC [dbo].[sp_GetStaffImage]
    @staffId varchar(150)
    as
    SELECT Stf.staffImage as 'Image' FROM tblStaff Stf WHERE 
    staffID=@staffId


.
.
.
.

string staffID = Convert.ToString(dataGridViewStaff.Rows[e.RowIndex].Cells["Staff Id"].Value);
..............
.............
..........
...........

SqlConnection con1 = new SqlConnection(cs);
con.Open();
SqlCommand cmd1 = new SqlCommand("sp_GetStaffImage", con);
cmd1.CommandType = CommandType.StoredProcedure;
cmd1.Parameters.AddWithValue("@staffId", staffID);
SqlDataAdapter sda1 = new SqlDataAdapter(cmd1);
DataSet ds = new DataSet();
sda1.Fill(ds);

if(ds.Tables[0].Rows.Count>0)
{
   var img = (byte[])ds.Tables[0].Rows[0][0];

   if (img != Null) //code if the data in column named staffImage is 
                    Binary data then show the image                        
                    in PictureBox1 from the database.
   {

         MemoryStream ms = new MemoryStream(img);
         pictureBox1.Image = new Bitmap(ms);
   }
   else  //code if the data in column named staffImage is Null then show the image in PictureBox1 
           from Resource folder .
   {
       pictureBox1.ImageLocation = "Resources/human.png";
   }

}
con.Close();

通过运行上面的代码我得到了如下异常: 无法将类型 'System.DBNull' 的对象转换为类型 'System.Byte[]'。

"Unable to cast object of type 'System.DBNull' to type xxx" 的异常是正确的,而且它也很简单,因为您试图从 DataRow 转换的列值是 DbNull。

如果您正在从 DataTable 中读取行,并且该列被键入为可为空的列,则您应该始终检查 DbNull。

例如,代码应该是这样的:

 var img = (byte[])(ds.Tables[0].Rows[0][0] == DbNull.Value ? null : ds.Tables[0].Rows[0][0]);

Unable to cast object of type 'System.DBNull' to type 'System.Byte[]

您的异常源于以下调用:

 var img = (byte[])ds.Tables[0].Rows[0][0];

由此产生:

 ds.Tables[0].Rows[0][0] // This is DBNull, you can't cast it to byte[]

您正在尝试将 System.DBNull 转换为 System.Byte[],但这不起作用。您需要先检查这个值,请看下面。

注意:还有 一种检查方法

 var img = ds.Tables[0].Rows[0][0] == DbNull.Value ? null : (byte[])ds.Tables[0].Rows[0][0];

@madreflection 建议的替代方法:

 var img = ds.Tables[0].Rows[0].Field<byte[]>(0);

作为替代答案,由于 SQL 服务器中的 IMAGE 列类型已被弃用,您可以使用 VARBINARY(MAX) NOT NULL 作为列类型并将默认值设置为 0x。

这样一来,您总能从查询中至少返回 byte[0],而不必担心 DBNull 检查。