I am playing with theSqlFileStream to store my (large) objects on a SQL Server (in a varbinary(max) column), but i can’t really get a it to do as i want to. I have been trying to find some articles specific for serializing and storing (not just reading files from disk to store) and how to do this most efficiently. Is there some “hidden” best practice articles that I just haven’t found yet? Or do someone have a nice example of how to do this?
My primary source is Using SqlFileStream with C# to Access SQL Server FILESTREAM Data
Edit:
Added example code, where the object DataObject must be stored in a SQL Server table using filestream. I expect that it would be possible to stream my object, into the database but i currently don’t know how to this in the best way, what do i need to do to the object to stream it and have in mind that the object can be >1 GB with very complex structures in it.
New edit:
I have tested it with data structures containing very little data <300 kb and there are no problems. Then i’m thinking if it is a buffer problem or similar?
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Transactions;
using System.Data.SqlClient;
using System.Data.SqlTypes;
using System.Data;
namespace QEStore
{
public class DataObject
{
private Dictionary<int, string> _values = new Dictionary<int, string>();
private string _objName;
}
public class Store
{
private string _connStr = "Data Source=127.0.0.1;Integrated Security=True;Initial Catalog=my_data;";
public void InsertObject(int id, DataObject data)
{
var insStmt =
@"insert into data (data_id) values (@dataID);
select data_value.PathName(), GET_FILESTREAM_TRANSACTION_CONTEXT() from data where data_id = @dataID;";
string serverPath;
byte[] serverTxn;
using (var ts = new TransactionScope())
{
using (var conn = new SqlConnection(this._connStr))
{
conn.Open();
using (var cmd = new SqlCommand(insStmt, conn))
{
cmd.Parameters.Add("@dataID", SqlDbType.Int).Value = id;
using (var reader = cmd.ExecuteReader())
{
reader.Read();
serverPath = reader.GetSqlString(0).Value;
serverTxn = reader.GetSqlBinary(1).Value;
reader.Close();
}
}
using (var dest = new SqlFileStream(serverPath, serverTxn, FileAccess.Write))
{
// How to write the DataObject to the database using SqlFileStream
// dest.Write(...);
}
}
ts.Complete();
}
}
}
}
I have tried serializing the object as following, but get an IOException error saying “The handle is invalid”:
using (var dest = new SqlFileStream(serverPath, serverTxn, FileAccess.Write))
{
var formatter = new BinaryFormatter();
formatter.Serialize(dest, data);
dest.Close();
}
I found the problem. The problem was that the build-in serializer could not handle the large data object, using protobuf-net instead worked.