Как сбросить или очистить MemoryStream? - PullRequest
0 голосов
/ 22 октября 2018

Это мой код для вставки изображения в базу данных Access.Проблема в том, когда я вставляю изображение игрока в первый раз, когда оно работает.но когда я добавляю другой проигрыватель в БД и выбираю другой образ, он берет первый.Как очистить MemoryStream с помощью VB.NET 2015.

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 голосов
/ 22 октября 2018

Несколько проблем с вашим кодом:

  • MemoryStream не нужно объявлять на уровне класса, если вы используете его только в одном методе.
  • Вам всегда нужно утилизировать поток после того, как вы закончите с ним (либо вызвав метод Dispose(), либо предпочтительно , заключив его в Using блок).
  • Весь смысл использования параметризованных запросов заключается в предотвращении SQL-инъекции .Поэтому вам нужно использовать параметры для всех ваших значений, а не только для изображения.

Попробуйте это:

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, они вам не нужны в объявлениитакже.Но если вы это сделаете, убедитесь, что, по крайней мере, вы не используете команду повторно.Удалите его и повторно инициализируйте или очистите его параметры .

Я бы порекомендовал что-то подобное для вашего 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
...