Store And Retrieve Using FILESTREAM From SQL Database

Today I will explain regarding storing and retrieving images, videos and other document files from SQL server using the FILESTREAM feature. If you are new to FILESTREAM then read my previous article FILESTREAM Feature In SQL Server.

We are taking one example with WPF application and SQL server 2008 for understanding.

First we are creating one database with FILESTREAM. Enable option then create one table with FILESTREAM column. Script for creating table is given below.

We are creating one WPF window application with image control, buttons and text box as shown in below image.

FILESTREAM

In this application you have to browse image file using browse button and then give some name to this image in text box and click on “Save photo To Database” button this will insert new records in database. After inserting record you have to click on “Load Photo from Database” button. This button will take last inserted image data from database and display in below image control

Below I have given XAML design code for creating above UI in WPF application.

MainWindow.xaml

  1. <Window x:Class="FILESTREAM_WPF.MainWindow"  
  2.         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"  
  3.         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"  
  4.         Title="MainWindow" WindowState="Maximized">  
  5.     <Grid>  
  6.         <Grid HorizontalAlignment="Center" VerticalAlignment="Center">  
  7.         <Grid.RowDefinitions>  
  8.             <RowDefinition Height="Auto"/>  
  9.             <RowDefinition Height="Auto"/>  
  10.             <RowDefinition Height="Auto"/>  
  11.             <RowDefinition Height="Auto"/>  
  12.             </Grid.RowDefinitions>  
  13.         <Grid.ColumnDefinitions>  
  14.             <ColumnDefinition Width="Auto"/>  
  15.             <ColumnDefinition Width="Auto"/>  
  16.         </Grid.ColumnDefinitions>  
  17.             <TextBox Name="txtFilePath" Grid.Column="0" Grid.Row="0" Width="280" Height="30" HorizontalAlignment="Left" Margin="5"></TextBox>  
  18.             <Button Name="btnBrowse" Grid.Column="1" Grid.Row="0" Width="150" Content="Browse Photo" Height="30" HorizontalAlignment="Right" Margin="5" Click="btnBrowse_Click"></Button>  
  19.             <TextBox Name="txtIamgeName" Grid.Column="0" Grid.Row="1" Width="280" Height="30" HorizontalAlignment="Left" Margin="5"></TextBox>  
  20.             <Button Name="btnSave" Grid.Column="1" Grid.Row="1" Width="150" Content="Save Photo To Database" Height="30" HorizontalAlignment="Right" Margin="5" Click="btnSave_Click"></Button>  
  21.             <Border Grid.Column="0" Grid.Row="3" Grid.ColumnSpan="2" BorderBrush="Black" BorderThickness="1" CornerRadius="3">  
  22.                 <Image Name="imImages" Grid.Column="0" Grid.Row="3" Grid.ColumnSpan="2" Width="400" Height="400"></Image>  
  23.             </Border>  
  24.             <Button Name="btnLoadFromDB" Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="2" Width="160" Content="Load Photo From Databse" Height="30" HorizontalAlignment="Center" Margin="5" Click="btnLoadFromDB_Click"></Button>  
  25.     </Grid>  
  26.     </Grid>  
  27. </Window>  

For browsing image you have write the below code on button click event.

  1. private void btnBrowse_Click(object sender, RoutedEventArgs e)  
  2. {  
  3.             Microsoft.Win32.OpenFileDialog dlg = new Microsoft.Win32.OpenFileDialog();  
  4.             Nullable<bool> result = dlg.ShowDialog();  
  5.             if (result == true)  
  6.             {  
  7.                 string filename = dlg.FileName;  
  8.                 txtFilePath.Text = filename;  
  9.             }  
  10. }  

Now for storing an image file in database, first we are creating table with file stream enable column. Script for creating Table is given below.

  1. CREATE TABLE TblPhotos(  
  2.    ID UNIQUEIDENTIFIER ROWGUIDCOL NOT NULL UNIQUE,  
  3.    Name VARCHAR(20),  
  4.    Images VARBINARY(MAX) FILESTREAM NULL,  
  5.    CreatedDate datetime default getdate()  
  6. )  

Now for storing the image we have to use below insert query.

  1. -- Declare a variable to store the image data  
  2. DECLARE @tImage AS VARBINARY(MAX)  
  3.    
  4. -- Load the image data  
  5. SELECT @tImage = CAST(bulkcolumn AS VARBINARY(MAX)) FROM OPENROWSET( BULK  
  6.             'C:\temp\MicrosoftMouse.jpg',  
  7.             SINGLE_BLOB ) AS x  
  8.               
  9. -- Insert data in table             
  10. INSERT INTO TblPhotos (ID, Name, Images) SELECT NEWID(), 'Image-1',@tImage   

In above query you have to pass local image path. If your SQL server has installed on different PC and your image is on local path then you have to give network path in above insert query. 

For inserting a record in database we have write below code on “Save Photo To Database” button click event.

  1. private void btnSave_Click(object sender, RoutedEventArgs e)  
  2. {  
  3.             SqlConnection conn = new SqlConnection("Your SQL Connection String");  
  4.             conn.Open();  
  5.             StringBuilder str = new StringBuilder();  
  6.             str.AppendLine("DECLARE @tImage AS VARBINARY(MAX)");  
  7.             str.AppendLine("SELECT @tImage = CAST(bulkcolumn AS VARBINARY(MAX)) FROM OPENROWSET( BULK '" + txtFilePath.Text + "', SINGLE_BLOB ) AS x");  
  8.             str.AppendLine("INSERT INTO TblPhotos (ID, Name, Images) SELECT NEWID(), '" + txtIamgeName.Text + "',@tImage");  
  9.   
  10.             SqlCommand cmd = new SqlCommand(str.ToString(), conn);  
  11.             cmd.ExecuteNonQuery();  
  12.             MessageBox.Show("Image Saved Successfully...");  
  13. }  

After successfully inserting an image in database, we have to retrieve image data from the database and display it in image control in WPF application.

Whatever data you have retrieved from the database it in byte array format so first you have to convert this byte array data to memory stream and then you have to pass this memory stream to the image control shown in below.

  1. private void btnLoadFromDB_Click(object sender, RoutedEventArgs e)  
  2. {  
  3.             SqlConnection conn = new SqlConnection("Your SQL Connection String ");  
  4.             conn.Open();  
  5.             SqlDataAdapter sda = new SqlDataAdapter("SELECT TOP 1 * FROM TBLPHOTOS ORDER BY CreatedDate desc", conn);  
  6.             DataSet ds = new DataSet();  
  7.             sda.Fill(ds);  
  8.             DataTable dt = ds.Tables[0];  
  9.   
  10.             if (dt!=null && dt.Rows.Count>0)  
  11.             {  
  12.                 byte[] btImage = dt.Rows[0]["Images"] as byte[];  
  13.   
  14.                 using (MemoryStream ms = new MemoryStream(btImage, 0, btImage.Length))  
  15.                 {  
  16.                     var imageSource = new BitmapImage();  
  17.                     ms.Position = 0;  
  18.                     imageSource.BeginInit();  
  19.                     imageSource.CreateOptions = BitmapCreateOptions.PreservePixelFormat;  
  20.                     imageSource.CacheOption = BitmapCacheOption.OnLoad;  
  21.                     imageSource.UriSource = null;  
  22.                     imageSource.StreamSource = ms;  
  23.                     imageSource.EndInit();  
  24.                     // Assign the Source property of your image  
  25.                     imImages.Source = imageSource;  
  26.                 }  
  27.             }  
  28. }  

As you seen in above code first we are fetching record from database using select query and then we are assigning database content to byte array and then we are creating memory stream from this byte array.

Then create BitmapImage from the memory stream and give this BitmapImage to image control.

In the above example we have shown the storing and retrieving image from the database but If you have any video file or any other document file then inserting of video or PFD file are same as image file, so you have to give path of that file. But when you want to retrieve any file from database then you have to create file from byte array using below code.

  1. public void ByteArrayToFile(string fileName, byte[] byteArray)  
  2. {  
  3.      try  
  4.      {  
  5.                 using (var fs = new FileStream(fileName, FileMode.Create, FileAccess.Write))  
  6.                 {  
  7.                     fs.Write(byteArray, 0, byteArray.Length);  
  8.                 }  
  9.      }  
  10.      catch (Exception)  
  11.      {  
  12.      }  
  13. }  

Using this above function you can create file from your byte array. You can use the above function  for creating a PDF file, video file, or any document files.

In the above function you have to provide path where you have to save your file.