Data Access has been discontinued. Please refer to this page for more information.

How to: Work with Data Streams

An entity in the Telerik Data Access model can expose binary large objects, also known as BLOBs. This binary data might represent video or audio streams, images, document files, or other types of binary media. Binary large objects (BLOBs) need different treatment, because they can contain gigabytes of data and this can affect the application performance. That's why Telerik Data Access provides special support (API) for working with BLOBs.

In this topic, you will see:

Working with the BinaryStream Type

The BinaryStream type is a special type that exposes a stream around a database binary field. By default when you map a table with a binary column, the corresponding property should be of type byte[].

The BinaryStream type can be used against varbinary(MAX) columns in MSSQL and the corresponding ones in other backends. For example, if you try to use it with a column of type Image, you will get an exception. The support backends/sql types are as follows:

  • MSSQL - varbinary(MAX)
  • PostgreSQL - bytea
  • MySql - longblob
  • Oracle - blob
public partial class Category
{
    public virtual int CategoryID { get; set; }
    public virtual string CategoryName { get; set; }
    public virtual string Description { get; set; }
    public virtual byte[] Picture { get; set; }
}
Partial Public Class Category
    Public Overridable Property CategoryID() As Integer
    Public Overridable Property CategoryName() As String
    Public Overridable Property Description() As String
    Public Overridable Property Picture() As Byte()
End Class

To use the new BinaryStream type you have to change the type of the property:

public partial class Category
{
    public virtual int CategoryID { get; set; }
    public virtual string CategoryName { get; set; }
    public virtual string Description { get; set; }
    public virtual BinaryStream Picture { get; set; }
}
Partial Public Class Category
    Public Overridable Property CategoryID() As Integer
    Public Overridable Property CategoryName() As String
    Public Overridable Property Description() As String
    Public Overridable Property Picture() As BinaryStream
End Class

Reading Binary Data From the Database

The following example shows how to use the Read method of the BinaryStream class to read an image from the database and save it on the local hard drive. The Read method reads a sequence of bytes from the current stream and advances the position within the stream by the number of bytes read.

using ( FluentModel dbContext = new FluentModel() )
{
   FileStream stream = new FileStream( "CategoryImage.jpg", 
        FileMode.Create, FileAccess.Write );
   BinaryWriter writer = new BinaryWriter( stream );

   Category firstCategory = dbContext.Categories.Last();

   int numBytesToRead = ( int )firstCategory.Picture.Length;
   byte[] bytes = new byte[65536];
   int bytesRead = 1;

   while ( numBytesToRead > 0 && bytesRead > 0 )
   {
       bytesRead = firstCategory.Picture.Read( bytes, 0, 
            Math.Min( numBytesToRead, bytes.Length ) );
       writer.Write( bytes );
       numBytesToRead -= bytesRead;
   }

   writer.Flush();
   writer.Dispose();
}
Using dbContext As New FluentModel()
    Dim stream As New FileStream("CategoryImage.jpg", FileMode.Create, 
        FileAccess.Write)
    Dim writer As New BinaryWriter(stream)

    Dim firstCategory As Category = dbContext.Categories.Last()

    Dim numBytesToRead As Integer = CInt(Fix(firstCategory.Picture.Length))
    Dim bytes(65535) As Byte
    Dim bytesRead As Integer = 1

    Do While numBytesToRead > 0 AndAlso bytesRead > 0
        bytesRead = firstCategory.Picture.Read(bytes, 0, 
            Math.Min(numBytesToRead, bytes.Length))
        writer.Write(bytes)
        numBytesToRead -= bytesRead
    Loop

    writer.Flush()
    writer.Dispose()
End Using

Writing Binary Data to the Database

The following example shows how to use the Write method of the BinaryStream class to insert an image in the database. The Write method writes a sequence of bytes to the current stream and advances the current position within the stream by the number of bytes written. Another important thing to note is the Append property of the BinaryStream class. It indicates whether the stream will replace the binary field with update statements or will just append the new data.

Note that the BinaryStream property is automatically initialized by the runtime. You don't need to explicitly create a new instance.

using ( FluentModel dbContext = new FluentModel() )
{
   Category category = new Category();
   category.CategoryName = "Demo Category";
   category.Description = "Demo Description";

   dbContext.Add( category );
   dbContext.SaveChanges();

   using ( FileStream stream = File.OpenRead( "Input.jpg" ) )
   {
       byte[] buffer = new byte[1024];
       int bytesRead = 0;
       while ( ( bytesRead = stream.Read( buffer, 0, buffer.Length ) ) > 0 )
       {
           category.Picture.Write( buffer, 0, bytesRead );
       }
   }

   category.Picture.Flush();
   dbContext.SaveChanges();
}
Using dbContext As New FluentModel()
    Dim _category As New Category()
    _category.CategoryName = "Demo Category"
    _category.Description = "Demo Description"

    dbContext.Add(_category)
    dbContext.SaveChanges()

    Using stream As FileStream = File.OpenRead("Input.jpg")
        Dim buffer(1023) As Byte
        Dim bytesRead As Integer = 0
        bytesRead = stream.Read(buffer, 0, buffer.Length)
        Do While bytesRead > 0
            _category.Picture.Write(buffer, 0, bytesRead)
            bytesRead = stream.Read(buffer, 0, buffer.Length)
        Loop
    End Using

    _category.Picture.Flush()
    dbContext.SaveChanges()
End Using