Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
cn.Open()
Dim arrimage() As Byte
Dim ms As New MemoryStream()
If (pb1.Image IsNot Nothing) Then
pb1.Image.Save(ms, pb1.Image.RawFormat)
arrimage = ms.GetBuffer
ms.Close()
End If
With cmd
.Connection = cn
.CommandText = "INSERT INTO [Example]([PName],[Pic])VALUES(@a2,@a1)"
.Parameters.Add("a0", OleDbType.VarChar).Value = tName.Text
.Parameters.Add("a1", OleDbType.Binary).Value = IIf(pb1.Image IsNot Nothing, arrimage, DBNull.Value())
.Dispose()
.ExecuteNonQuery()
End With
cn.Close()
End Sub
答案 0 :(得分:1)
您的代码中存在多个问题。按顺序出现:
不要使用GetBuffer()
如MSDN所述,缓冲区的大小可以是流中数据的两倍。这将使用额外的空值不必要地膨胀数据库。请改用ToArray()
。
由于数据库中的图像必须与字节数组进行转换,因此请考虑将图像存档到文件夹并仅将名称存储在数据库中。然后,您可以预先添加存档文件夹名称以快速加载图像。
而不是 RawFormat ,我会将其编码为类似JPEG的内容。
使用Using
块
通常需要处理任何具有.Dispose
方法的东西。这将适用于OleDBCommand
对象(MemStream确实不需要处理,但这是一个实现细节)。
Using
阻止Dim
,New
和Dispose
加入一个方便易用的区块:
Using foo As New FooBar()
...
End Using
第一行声明一个foo
变量,并创建一个FooBar
的实例,您可以在该块中使用它。最后,它会自动处理。
不要使用全局DBCommand对象
您的代码未显示正在声明或创建的cmd
,因此它必须是表单级对象。 不要这样做。除非您的所有应用程序都是一回事,否则对DBCommand
对象没有任何可重用性。
在代码中添加2个参数。下次你去使用它时,它仍然可以有那些2,代码将增加2个,这比SQL查询所需的更多。在这种情况下,代码处理它,但 表示下次引用它时,您将得到ObjectDisposedException
。
Dispose
之前调用ExecuteNonQuery
会崩溃 - 您无法使用已处置的对象。 DBNull.Value
不是方法
至于编译器错误,你有这个:
IIf(pb1.Image IsNot Nothing, arrimage, DBNull.Value())
DBNull.Value是一个属性,而不是一个方法,所以不需要parens。此外,你应该使用" new" If
运算符而非旧IIF
函数。运算符被短路,因此忽略不适用的part /子句:
' should evaluate the data (arrimage) not its source
If(pb1.Image IsNot Nothing, arrimage, DBNull.Value) ' no parens
修改后的代码:
cn.Open()
Dim arrimage() As Byte = Nothing
If (pb.Image IsNot Nothing) Then
Using ms As New MemoryStream()
pb.Image.Save(ms, ImageFormat.Jpeg)
arrimage = ms.ToArray()
End Using
End If
Dim sql = "INSERT INTO [Example]([PName],[Pic]) VALUES (@a2,@a1)"
Using cmd As New OleDbCommand(sql, cn)
cmd.Parameters.Add("a0", OleDbType.VarChar).Value = tName.Text
If arrimage IsNot Nothing Then
cmd.Parameters.Add("a1", OleDbType.VarBinary).Value = arrimage
Else
cmd.Parameters.Add("a1", OleDbType.VarBinary).Value = DBNull.Value
End If
cmd.ExecuteNonQuery()
End Using
cn.Close()