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

Artificial Types and BinaryStream Properties

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.

This topic demonstrates how to work with artificial types that expose BinaryStream properties. The Telerik.OpenAccess.BinaryStream type is a special type that exposes a stream around a database binary field. It allows you to read/write binary large objects (BLOBs) to the database. For more information, take a look at Working with Streams.

In this topic:

Mapping BinaryStream Properties

Mapping BinaryStream properties is straightforward and there isn't anything specific. The following example is taken from the Mapping Artificial Types topic where the CategoryImage property is defined as byte[]. Now it is defined as BinaryStream. This will map the CategoryImage property to a database column of type varbinary(MAX).

categoryConfiguration.HasArtificialProperty<BinaryStream>( "CategoryImage" );
categoryConfiguration.HasArtificialProperty(Of BinaryStream())("CategoryImage")

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. Another specific moment is the usage of the FieldValue<BinaryStream> method.

using ( FluentModelContext fluentContext = new FluentModelContext() )
{
   object category = fluentContext.GetAll( "FluentModel.Category" ).
       Where( string.Format( "Id = {0}", 1 ) ).Cast<object>().FirstOrDefault();

   FileStream stream = new FileStream( "CategoryImage.jpg", FileMode.Create, FileAccess.Write );
   BinaryWriter writer = new BinaryWriter( stream );
   int numBytesToRead = ( int )category.FieldValue<BinaryStream>( "CategoryImage" ).Length;
   byte[] bytes = new byte[65536];
   int bytesRead = 1;

   while ( numBytesToRead > 0 && bytesRead > 0 )
   {
       bytesRead = category.FieldValue<BinaryStream>( "CategoryImage" ).Read( bytes, 0, Math.Min( numBytesToRead, bytes.Length ) );
       writer.Write( bytes );
       numBytesToRead -= bytesRead;
   }

   writer.Flush();
   writer.Dispose();
}
Using fluentContext As New FluentModelContext()
    Dim category As Object = fluentContext.GetAll("FluentModel.Category").
        Where(String.Format("Id < {0}", 10)).Cast(Of Object).FirstOrDefault()

    Dim stream As New FileStream("CategoryImage.jpg", FileMode.Create, FileAccess.Write)
    Dim writer As New BinaryWriter(stream)
    Dim numBytesToRead As Integer = CInt(Fix(
            Telerik.OpenAccess.ExtensionMethods.FieldValue(Of BinaryStream)(category, "CategoryName").Length))
    Dim bytes(65535) As Byte
    Dim bytesRead As Integer = 1

    Do While numBytesToRead > 0 AndAlso bytesRead > 0
        bytesRead = Telerik.OpenAccess.ExtensionMethods.FieldValue(Of BinaryStream)(category, "CategoryName").
            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.

using ( FluentModelContext fluentContext = new FluentModelContext() )
{
   object product = fluentContext.CreateInstance( "FluentModel.Product" );
   fluentContext.Add( product );
   product.SetFieldValue( "ProductName", "My Product" );
   product.SetFieldValue( "Price", 24 );

   object category = fluentContext.CreateInstance( "FluentModel.Category" );
   fluentContext.Add( category );
   category.SetFieldValue( "CategoryName", "MyCategory" );
   category.SetFieldValue( "Description", "New Description" );

   product.SetFieldValue( "Category", category );

   fluentContext.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.FieldValue<BinaryStream>( "CategoryImage" ).Write( buffer, 0, bytesRead );
       }
   }

   category.FieldValue<BinaryStream>( "CategoryImage" ).Flush();
   fluentContext.SaveChanges();
}
Using fluentContext As New FluentModelContext()
    Dim product As Object = fluentContext.CreateInstance("FluentModel.Product")
    fluentContext.Add(product)
    product.SetFieldValue("ProductName", "My Product")
    product.SetFieldValue("Price", 24)

    Dim category As Object = fluentContext.CreateInstance("FluentModel.Category")
    fluentContext.Add(category)
    category.SetFieldValue("CategoryName", "MyCategory")
    category.SetFieldValue("Description", "New Description")

    product.SetFieldValue("Category", category)

    fluentContext.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
            Telerik.OpenAccess.ExtensionMethods.FieldValue(Of BinaryStream)(category, "CategoryName").Write(buffer, 0, bytesRead)
            bytesRead = stream.Read(buffer, 0, buffer.Length)
        Loop
    End Using

    Telerik.OpenAccess.ExtensionMethods.FieldValue(Of BinaryStream)(category, "CategoryName").Flush()
    fluentContext.SaveChanges()
End Using