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
A
回答
1
您在代碼中有多個問題。爲了外觀:
不使用的GetBuffer()
正如上MSDN提到的,緩衝液可以是高達流中的數據的大小的兩倍。這會使數據庫不必要地增加額外的空值。改爲使用ToArray()
。
由於數據庫中的圖像必須轉換爲字節數組以及從字節數組轉換,因此可以考慮將圖像歸檔到文件夾並將名稱存儲在數據庫中。然後,您可以預先安裝存檔文件夾名稱以快速加載圖像。
而不是RawFormat,我會將它編碼爲像JPEG一樣。
使用Using
塊
任何具有.Dispose
方法通常需要被設置。這將適用於OleDBCommand
對象(MemStream實際上不需要處理,但這是一個實現細節)。
Using
塊incoporate 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是一個屬性,而不是方法,所以括號都沒有需要。另外,您應該使用「新」If
運算符而不是舊的IIF
函數。操作者被短路,從而不適部件/子句被忽略:
' 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()
- 由於命令對象是無用的,而不查詢和連接兩者,我更喜歡在構造函數中傳遞它們。它使代碼更短以及確保它具有它所需要的功能
- 還應該創建,使用和每次處理連接
- 創建一個方便的擴展方法可以將圖像轉換爲字節數組
相關問題
- 1. 類'clsGetHeaderValue'不能被索引,因爲它沒有默認屬性
- 2. 類'System.Web.UI.WebControls.TableRow'無法被索引,因爲它沒有默認屬性
- 3. 類「<classname>」不能被索引,因爲它沒有默認屬性
- 4. 結構無法被索引,因爲它沒有默認屬性
- 5. 無法索引,因爲它沒有默認屬性錯誤
- 6. 我在做什麼錯誤:結構無法被索引,因爲它沒有默認屬性(WITH CLAUSE)
- 7. VB集合無法被索引,因爲它沒有默認屬性?如何迭代集合?
- 8. 默認索引屬性
- 9. VB列表框無法編入索引,因爲它沒有默認值
- 10. 「沒有默認屬性」
- 11. 如何實現索引[]默認屬性
- 12. ,因爲它被認爲
- 13. 屬性或索引「string.this [INT]」不能被分配到 - 它只是
- 14. 對象不能被刪除,因爲它沒有在ObjectStateManager
- 15. @類型/道具類型/索引沒有默認出口
- 16. 。它沒有默認值,也不能爲空
- 17. 什麼是UIBarButtonItem的默認高度,因爲它不能是20?
- 18. C++默認類屬性
- 19. XMLReader不能讀取默認屬性
- 20. QML:委託的索引屬性不被認可的console.log()
- 21. 屬性默認爲原子
- 22. 做屬性默認爲零?
- 23. 如何將ListBox.Rows屬性重置爲默認值(沒有硬編碼默認值)
- 24. 默認屬性
- 25. 默認屬性
- 26. 類的初始化 - 屬性沒有默認構造函數
- 27. 有沒有辦法將類型的屬性設置爲默認值?
- 28. 爲什麼Phantom引用沒有被清除,因爲它們被排入隊列?
- 29. 不能刪除模式,因爲它正在被對象引用
- 30. 'int'類型的值不能用作默認參數,因爲沒有類型爲C#的標準轉換。
有幾件事,首先你要在執行查詢之前處理你的命令。你應該執行然後處理。 – Codexer
'DBNull.Value()'值是屬性而不是方法 – Plutonix
不是'使用'比'.Close'或'.Dispose'更習慣的選擇嗎? @Zaggler –