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
- Reading Binary Data From the Database
- Writing Binary Data to the Database
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