Spesso quando si maneggiano dati che hanno riferimenti ad immagini (tipo cataloghi o cose simili) si tende ad evitare (se possibile) di memorizzare all'interno delle tabelle direttamente tutto il file con campi BLOB.
Questo perche si appesantisce il database, l'applicazione, e non si puo' aggiornare un' immagine all'ultima versione in maniera "agile" sovrascrivendo il file.
Si tende invece a inserire il percorso
UNC in un campo e a caricare il file quando viene richiesto.
Data la potenza di un oggetto come
Crystal Report che supporta i campi
BLOB egregiamente, ci si aspetta che sia in grado di fare per noi questo caricamento "al volo" ma cosi purtroppo non è fino alla versione
XI come spiegano qui:
http://www.businessobjects.com/products/reporting/crystalreports/whatsnew.asp Allora per farlo lo stesso nelle precedenti versioni, si puo' decidere di "ingannare" il report, dandogli in pasto un campo fittizio e dicendogli che sia di tipo
BLOB.
Cosa importantissima è appunto creare la struttura giusta con cui creare il report in fase di design in modo che si aspetti questa tipologia di campo, magari creando un database temporaneo Access dove replichiamo la struttura e ci aggiungiamo in coda il campo
Image (
"oggetto ole" per Access)
Proprio per quanto riguarda
Access bisogna aggiungerlo a mano da dentro
Access stesso perchè non supporta una conversione a questo tipo direttamente da query SQL, cosa che invece su
SQL/MSDE si puo' fare tranquillamente con questa sintassi:
SELECT *, CONVERT(image,'') AS Immagine FROM MiaTabellaCosi al Report nel caso di
Access devo dare il Database con il campo
BLOB e nel caso di
SQL posso tranquillamente dargli un "comando" ovvero una stringa SQL senza creare campi sul DB.
A parte questa differenza che ci semplificherebbe la vita in fase di progettazione per il resto in questo campo ci dobbiamo preoccupare noi di aggiungere il contenuto in
Byte[] (campo
BLOB appunto) per ogni riga caricandolo dal valore del
Path che abbiamo nella stessa riga utilizzando il
FileStream dal namespace
Sytem.IO:
private byte[] GetFile(string filePath)
{
FileStream str = new FileStream(filePath,FileMode.Open,FileAccess.Read);
byte[] b = new byte[str.Length];
str.Read(b, 0, b.Length);
return b;
}
e lo si carica per ogni record che risulta della mia tabella:
//---- leggo i file immagine e poi li parcheggio nel DB nella colonna OLE
foreach(DataRow riga in miaTab.Rows)
riga["immagine"] = GetFile((string)riga["pathimg"]);
Da tenere presente che comunque si sovraccarica un po' il programma in quanto si crea in memoria una tabella che contiene gli n byte delle immagini (e quindi dal
Task Manager si puo' vedere che le risorse utilizzate aumentano) e si girano su tutte le righe percui sicuramente all'aumentare delle righe si ha un degrado delle prestazioni.
Finchè non ci viene dato il runtime della versione
XI pero' non si puo' fare altrimenti ;-)
Download del Codice d'esempiohttp://www.dotnethell.it/files/Crystal_Blob.zip