Questo post possiamo considerarlo come integrazione all'articolo di Sabrina dal titolo: Memorizzare immagini in SQL Server. Considerato che su connessioni lente la gestione di immagini salvate in un DataBase può risultare pesante su tutta la rete, personalmente utilizzo questo metodo (ne ho provati diversi ma questo è secondo me il più efficace e flessibile).
Nella tabella dove memorizzo l'immagine ho inserito un campo aggiuntivo di tipo varchar(40) ove memorizzo l'Hash dell'immagine (20Byte) convertito il esadecimale (40 String). L'immagine la salvo anche in locale su disco (directory Documenti-->Immagini dell'utente) nel formato che mi interessa con il nome del file uguale al suo Hash. Al momento in cui l'immagine deve essere utilizzata verifico se l'Hash memorizzato su DB è presente su disco, se non esiste significa che l'immagine in locale non è allineata con quella presente sul DB per cui ricarico l'immagine da DB altrimenti utilizzo quella salvata in locale. Chiaramente ogni volta che aggiorno l'immagine su DB (da qualsiasi postazione client) aggiorno anche il nuovo Hash sul DB. Segue il codice di una classe che permette di gestire questo:
Public
_Immagine = Value
_Immagine =
CmdDb.CommandText =
xDr = CmdDb.ExecuteReader(CommandBehavior.SequentialAccess)
iLen = xDr.GetBytes(0, 0,
_Immagine = Image.FromStream(xSt,
_Immagine =
_Immagine =
xDr.Close()
_Immagine.Save(ImagesPath & HashMemorizzato, _Immagine.RawFormat)
MessageBox.Show(ex.Message,
xDr.Close()
xDr.Close()
_Immagine =
MessageBox.Show(ex.Message,
xDr.Close()
_Immagine.Save(xMs, _Immagine.RawFormat)
xMs.Close()
Hash += b.ToString(
_Immagine.Save(ImagesPath & Hash)
CmdDb.Parameters.Add(
IO.File.Delete(ImagesPath & Hash)
MessageBox.Show(ex.Message,
MsgBox(
End
Saluti,
Alberto De Luca
Class DBImmaginePrivate ImagesPath As String = Environment.GetFolderPath(Environment.SpecialFolder.MyPictures) & "\"Private _Immagine As ImagePublic Property Immagine() As ImageGetReturn _ImmagineEnd GetSet(ByVal Value As Image)End SetEnd PropertyPublic Function LoadData(ByVal DBConnection As SqlClient.SqlConnection) As BooleanDim CmdDb As New SqlClient.SqlCommand("SELECT Hash FROM TabellaImmagine WHERE(IDImmagine=1)", DBConnection)Dim HashMemorizzato As String = CmdDb.ExecuteScalarDim DownloadNecessario As Boolean = Not IO.File.Exists(ImagesPath & HashMemorizzato)If DownloadNecessario ThenDim xDr As SqlClient.SqlDataReaderTryNothing"SELECT Immagine FROM TabellaImmagine WHERE(IDImmagine=1)"If xDr.Read ThenDim iLen As IntegerTryIf Not xDr.IsDBNull(0) ThenNothing, 0, Integer.MaxValue)If iLen > 1 ThenDim xBuff(iLen) As ByteIf xDr.GetBytes(0, 0, xBuff, 0, xBuff.Length) > 0 ThenTrue)Dim xSt As New IO.MemoryStream(xBuff)End IfElseNothingEnd IfElseNothingEnd IfReturn TrueCatch ex As Exception"Errore immagine", MessageBoxButtons.OK, MessageBoxIcon.Error)Return FalseFinallyIf Not xDr.IsClosed ThenEnd IfEnd TryElseIf Not IsNothing(_Immagine) ThenNothingEnd IfReturn FalseEnd IfReturn TrueCatch ex As Exception"Errore immagine", MessageBoxButtons.OK, MessageBoxIcon.Error)Return FalseFinallyIf Not xDr.IsClosed ThenEnd IfEnd TryEnd IfEnd FunctionPublic Function SaveData(ByVal DBConnection As SqlClient.SqlConnection) As BooleanIf _Immagine IsNot Nothing ThenDim CmdDb As New SqlClient.SqlCommand("SELECT Hash FROM TabellaImmagine WHERE(IDImmagine=1)", DBConnection)Dim sha As New System.Security.Cryptography.SHA1CryptoServiceProviderDim xMs As New IO.MemoryStreamDim b As ByteDim Hash As StringDim Buffer As Byte() = xMs.GetBufferDim result As Byte() = sha.ComputeHash(Buffer)For Each b In result"&H")NextTryIf Hash <> CmdDb.ExecuteScalar ThenNew SqlClient.SqlParameter("@Immagine", SqlDbType.Image)).Value = BufferDim strSQL As String = "UPDATE TabellaImmagine SET Immagine = @Immagine WHERE(IDImmagine=1)"If CmdDb.ExecuteNonQuery > 0 ThenReturn TrueElseReturn FalseEnd IfEnd IfCatch ex As Exception"Errore immagine", MessageBoxButtons.OK, MessageBoxIcon.Error)Return FalseEnd TryElse"Immagine non valida")End IfEnd Function Class