#sql-server #vb.net
#sql-сервер #vb.net
Вопрос:
У меня есть изображения, назначенные каждой кнопке в моем VB.NET форма, изображения поступают с SQL Server. Тип данных varbinary(MAX)
равен .
Это мой код:
Using con As New SqlConnection("con string")
Dim sql As String = "SELECT * FROM Inventory WHERE ID=@ID"
Using cmd As New SqlCommand(sql, con)
cmd.Parameters.Add("@ID", SqlDbType.VarChar).Value = 3
con.Open()
Using myreader As SqlDataReader = cmd.ExecuteReader()
If myreader.Read() AndAlso Not DBNull.Value.Equals(myreader("Image")) Then
Boton3.Text = myreader("Item")
Boton3.Enabled = myreader("ONOFF")
Dim ImgSql() As Byte = DirectCast(myreader("Image"), Byte())
Using ms As New MemoryStream(ImgSql)
Boton3.BackgroundImage = Image.FromStream(ms)
con.Close()
End Using
Else
Boton3.Text = myreader("Item")
Boton3.BackgroundImage = Nothing
Boton3.Enabled = myreader("ONOFF")
End If
End Using
End Using
End Using
Платформа 64-битная. Я думаю, что это может быть связано с неправильной утилизацией, но я не уверен, поскольку я новичок в кодировании.
РЕДАКТИРОВАТЬ, ПОКАЗЫВАЯ НОВЫЙ КОД И ТО, КАК Я ВОССТАНАВЛИВАЮ БОЛЕЕ ОДНОЙ ЗАПИСИ:
Private Sub Button12_Click(sender As Object, e As EventArgs) Handles Button12.Click
Dim dt As DataTable
Try
dt = GetInventoryDataByID(1)
Catch ex As Exception
MessageBox.Show(ex.Message)
Exit Sub
End Try
If dt.Rows.Count > 0 Then
Boton1.Text = dt.Rows(0)("Articulo").ToString
Boton1.Enabled = CBool(dt.Rows(0)("ONOFF"))
If Not DBNull.Value.Equals(dt.Rows(0)("Imagen")) Then
Dim ImgSql() As Byte = DirectCast(dt.Rows(0)("Imagen"), Byte())
Using ms As New MemoryStream(ImgSql)
Boton1.BackgroundImage = Image.FromStream(ms)
End Using
Else
Boton1.BackgroundImage = Nothing
End If
Else
MessageBox.Show("No records returned")
End If
Dim dt2 As DataTable
Try
dt2 = GetInventoryDataByID(2)
Catch ex As Exception
MessageBox.Show(ex.Message)
Exit Sub
End Try
If dt2.Rows.Count > 0 Then
Boton2.Text = dt2.Rows(0)("Articulo").ToString
Boton2.Enabled = CBool(dt2.Rows(0)("ONOFF"))
If Not DBNull.Value.Equals(dt2.Rows(0)("Imagen")) Then
Dim ImgSql() As Byte = DirectCast(dt2.Rows(0)("Imagen"), Byte())
Using ms As New MemoryStream(ImgSql)
Boton2.BackgroundImage = Image.FromStream(ms)
End Using
Else
Boton2.BackgroundImage = Nothing
End If
Else
MessageBox.Show("No records returned")
End If
End Sub
Private Function GetInventoryDataByID(id As Integer) As DataTable
Dim dt As New DataTable
Dim sql As String = "SELECT Imagen, Articulo, ONOFF FROM Inventario WHERE ID=@ID"
Using con As New SqlConnection("CON STRING"),
cmd As New SqlCommand(sql, con)
cmd.Parameters.Add("@ID", SqlDbType.Int).Value = id
con.Open()
Using myreader As SqlDataReader = cmd.ExecuteReader()
dt.Load(myreader)
End Using
End Using
Return dt
End Function
End Class
Комментарии:
1. К вашему сведению, интересная статья
2. Это сообщение об ошибке также может означать, что с данными что-то не так. Если вы сохраните данные на диск, можете ли вы открыть их как изображение с помощью чего-то вроде IrfanView?
3. В какой строке ошибка кода?
4. @AndrewMorton Я могу открыть изображение в другом программном обеспечении под названием photo paint.
5. @привет, о Нет! Как мы вообще собираемся найти проблему? Итак, что заставляет вас думать, что код, который вы показываете в вопросе, является проблемой? Вы прокомментировали код, который извлекает изображение? (Пожалуйста, имейте в виду, что мы не можем видеть через камеру наблюдения, которая просматривает ваш монитор в данный момент из-за технического обслуживания.)
Ответ №1:
Вы не хотите удерживать соединение открытым во время обновления пользовательского интерфейса. Отделите код пользовательского интерфейса от кода вашей базы данных.
Если вы поставите запятую в конце первой строки внешнего блока Using , и команда, и соединение будут включены в один и тот же блок. Сохраняет немного отступов.
Вы передаете целое число в @ID
параметр, но вы установили SqlDbType
как VarChar
. Похоже на проблему. Я изменил значение SqlDbType
на Int
.
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim dt As DataTable
Try
dt = GetInventoryDataByID(3)
Catch ex As Exception
MessageBox.Show(ex.Message)
Exit Sub
End Try
If dt.Rows.Count > 0 Then
Boton3.Text = dt.Rows(0)("Item").ToString
Boton3.Enabled = CBool(dt.Rows(0)("ONOFF"))
If Not DBNull.Value.Equals(dt.Rows(0)("Image")) Then
Dim ImgSql() As Byte = DirectCast(dt.Rows(0)("Image"), Byte())
Using ms As New MemoryStream(ImgSql)
Boton3.BackgroundImage = Image.FromStream(ms)
End Using
Else
Boton3.BackgroundImage = Nothing
End If
Else
MessageBox.Show("No records returned")
End If
End Sub
Private Function GetInventoryDataByID(id As Integer) As DataTable
Dim dt As New DataTable
Dim sql As String = "SELECT * FROM Inventory WHERE ID=@ID"
Using con As New SqlConnection("con string"),
cmd As New SqlCommand(sql, con)
cmd.Parameters.Add("@ID", SqlDbType.Int).Value = id
con.Open()
Using myreader As SqlDataReader = cmd.ExecuteReader()
dt.Load(myreader)
End Using
End Using
Return dt
End Function
РЕДАКТИРОВАТЬ Добавить удаление на изображение
If Not DBNull.Value.Equals(dt.Rows(0)("Image")) Then
Dim ImgSql() As Byte = DirectCast(dt.Rows(0)("Image"), Byte())
Using ms As New MemoryStream(ImgSql)
If Boton3.BackgroundImage IsNot Nothing Then
Boton3.BackgroundImage.Dispose()
End If
Boton3.BackgroundImage = Image.FromStream(ms)
End Using
Else
If Boton3.BackgroundImage IsNot Nothing Then
Boton3.BackgroundImage.Dispose()
End If
End If
Комментарии:
1. Я попробовал ваше решение на
mybase.load
событии. Я все еще получаю ту же ошибку. Ошибка возникает только тогда, когда изображение имеет более одной кнопки (всего 15 кнопок). Ошибка также возникает, как только я загружаю форму. Он не показывает, в какой строке кода он выдает ошибку, но он показываетYour app has entered a break state, but there is no code to show because all threads were executing external code (typically system or framework code).
2. Ваш код показывает возврат одной записи. Покажите код, в котором вы извлекаете более одной записи. В целях тестирования переместите код из формы
Form_Load
и нажмите кнопку на форме, чтобы выполнить операцию.3. Спасибо за ответ, Мэри. Я отредактировал свой вопрос, чтобы показать, как я извлекаю более одной записи. Я также протестировал операцию на a
Button_Click
, и появилась та же ошибка.4. Я добавил вызов Dispose для изображения. Это может помочь решить проблемы с памятью.
5. Я решил эту проблему, просто не используя кнопки. Вместо этого я использовал pictureboxes в качестве кнопок, и это решило проблему. Я предполагаю, что проблема в том, что кнопки не позволяют использовать столько памяти, сколько pictureboxes. Я все равно приму ваш ответ, поскольку многому научился из вашего кода. Спасибо, Мэри!
Ответ №2:
Я решил эту проблему, просто не используя кнопки. Вместо этого я использовал pictureboxes в качестве кнопок, и это решило проблему. Я предполагаю, что проблема в том, что кнопки не позволяют использовать столько памяти, сколько pictureboxes.