如何重置或清除MemoryStream?

时间:2018-10-22 10:36:15

标签: vb.net reset memorystream

这是我的代码,用于将图像插入Access DB。问题是,当我第一次插入播放器图像时,它就起作用了。但是,当我将另一个播放器添加到数据库并选择另一个图像时,它将使用第一个图像。 如何使用VB.NET 2015清除MemoryStream。

Dim conn As New OleDbConnection("provider=microsoft.ace.oledb.12.0; Data Source=SoccerTimeDB.accdb")
Dim cmd As New OleDbCommand("", conn)
Dim ms As New MemoryStream
Sub Runcommand(Sqlcommand As String, Optional message As String = "")
    Try
        If conn.State = ConnectionState.Closed Then conn.Open()
        cmd.CommandText = Sqlcommand
        cmd.ExecuteNonQuery()
        If message <> "" Then MsgBox(message)
    Catch ex As Exception
        MsgBox(ex.Message)
    Finally
        If conn.State = ConnectionState.Open Then conn.Close()
    End Try
End Sub

Private Sub btnAdd_Click(sender As Object, e As EventArgs) Handles btnAdd.Click
    playerImage.Image.Save(ms, playerImage.Image.RawFormat)
    Dim img() As Byte
    img = ms.ToArray()
    Dim strCmd As String = "insert into playerData values (" & playerNumberTB.Text & "," & playerIdTB.Text & ",'" & playerNameTB.Text & "', @Img) "

    cmd.Parameters.AddWithValue("@Img", img)
    Runcommand(strCmd, "player has been added")
End Sub

1 个答案:

答案 0 :(得分:2)

您的代码存在一些问题:

  • 如果仅在一种方法中使用MemoryStream,则不必在类级别上声明它。
  • 处理完流后,您总是需要对其进行处理(通过调用Dispose()方法或通过将其包装在Using块中来最好)。
  • 使用参数化查询的全部目的是为了防止SQL injection。因此,您需要对所有值使用参数,而不仅仅是图像。

尝试一下:

Dim img() As Byte
Using ms As New MemoryStream()
    playerImage.Image.Save(ms, playerImage.Image.RawFormat)
    img = ms.ToArray()
End Using

Dim strCmd As String = 
    "INSERT INTO playerData VALUES (@PlayerNumber, @PlayerId, @PlayerName, @Img)"
cmd.Parameters.AddWithValue("@PlayerNumber", playerNumberTB.Text)
cmd.Parameters.AddWithValue("@PlayerId", playerIdTB.Text)
cmd.Parameters.AddWithValue("@PlayerName", playerNameTB.Text)
cmd.Parameters.AddWithValue("@Img", img)
Runcommand(strCmd, "player has been added")

注意:您需要从声明中删除Dim ms As New MemoryStream行,因为它不再需要了。


更新:

OleDbConnection和OleDbCommand同样适用,声明中也不需要它们。但是,如果这样做,至少要确保不要重用该命令。处置并重新初始化它或clear its parameters

对于您的RunCommand方法,我推荐这样的方法:

Private ConnString As String = 
    "provider=microsoft.ace.oledb.12.0; Data Source=SoccerTimeDB.accdb"

Sub Runcommand(cmdText As String, Optional message As String = "")
    Using conn As New OleDbConnection(ConnString)
        Using cmd As New OleDbCommand(cmdText, conn)
            Try
                conn.Open()
                cmd.ExecuteNonQuery()
                If Not String.IsNullOrEmpty(message) Then MsgBox(message)
            Catch ex As Exception   ' Try to catch specific exceptions instead.
                MsgBox(ex.Message)
            End Try                 ' You don't need the `Finally` block anymore.
        End Using
    End Using
End Sub