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

Working with Streams

This article is relevant to entity models that utilize the deprecated Visual Studio integration of Telerik Data Access. The current documentation of the Data Access framework is available here.

An entity in the Telerik Data Access domain 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:

BinaryStream Class

The Telerik.OpenAccess.BinaryStream type is a special type that exposes a stream around a database binary field.

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

It derives from the Stream class, so you can use it as any other Stream object.

The BinaryStream type is not serializable.

The most important methods and properties of the BinaryStream class are as follows:

  • Append - indicates whether the stream will replace the binary field with update statements or will just append the new data. The Append property is demonstrated in the Writing Binary Data to the Database example.
  • Dispose - disposes the stream, by writing any changes to the backing store and closing the stream to release resources. The specific moment is that the Dispose method will flush all reads and writes.
  • Seek - sets the position within the current stream.
  • SetLength - sets the length of the current stream to the given value.

Reading Binary Data From the Database

The main purpose of the BinaryStream class is to read/write BLOBs from/to the database. The following example demonstrates how to read binary data from the database. In this particular example, you will read an image from the database and save it on the local hard drive.

using ( EntitiesModel dbContext = new EntitiesModel() )
{
   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 EntitiesModel()
    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

Analogically, you can write binary data in the database.

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

using ( EntitiesModel dbContext = new EntitiesModel() )
{
   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 EntitiesModel()
    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

How to Set a BinaryStream Property to Null

The following example demonstrates how to set a BinaryStream property to null.

using (EntitiesModel dbContext = new EntitiesModel())
{
   Category category = dbContext.Categories.FirstOrDefault();
   category.Picture = null;
   dbContext.SaveChanges();
}
Using dbContext As New EntitiesModel()
    Dim _category As Category = dbContext.Categories.FirstOrDefault()
    _category.Picture = Nothing
    dbContext.SaveChanges()
End Using

Attaching Objects with BinaryStream Properties

This section demonstrates how to attach and detach objects with BinaryStream properties. Basically, when you want to attach an object with a BinaryStream property you have to perform the following steps:

  1. Pass the object to the AttachCopy method of the context.
  2. Call FlushChanges.
  3. Initialize the BinaryStream property.
  4. Call SaveChanges.
using ( EntitiesModel dbContext = new EntitiesModel() )
{
   Category category = new Category();
   category.CategoryName = "Demo Category";
   category.Description = "Demo Descripton";

   Category attachedCategory = dbContext.AttachCopy( category );
   dbContext.FlushChanges();

   FileStream stream = File.OpenRead( "Input.jpg" );
   int numBytesToWrite = ( int )stream.Length;
   byte[] bytes = new byte[65536];
   int bytesRead = 1;

   while ( numBytesToWrite > 0 && bytesRead > 0 )
   {
       bytesRead = stream.Read( bytes, 0, Math.Min( numBytesToWrite, bytes.Length ) );
       attachedCategory.Picture.Write( bytes, 0, bytes.Length );
       numBytesToWrite -= bytesRead;
   }

   dbContext.SaveChanges();
   stream.Dispose();
}
Using dbContext As New EntitiesModel()
    Dim _category As New Category()
    _category.CategoryName = "Demo Category"
    _category.Description = "Demo Descripton"

    Dim attachedCategory As Category = dbContext.AttachCopy(_category)
    dbContext.FlushChanges()

    Dim stream As FileStream = File.OpenRead("Input.jpg")
    Dim numBytesToWrite As Integer = CInt(Fix(stream.Length))
    Dim bytes(65535) As Byte
    Dim bytesRead As Integer = 1

    Do While numBytesToWrite > 0 AndAlso bytesRead > 0
        bytesRead = stream.Read(bytes, 0, Math.Min(numBytesToWrite, bytes.Length))
        attachedCategory.Picture.Write(bytes, 0, bytes.Length)
        numBytesToWrite -= bytesRead
    Loop

    dbContext.SaveChanges()
    stream.Dispose()
End Using