使用SqlFileStream在SQL Server中序列化和存储大型对象
本文关键字:存储 大型 对象 序列化 SqlFileStream SQL Server 使用 | 更新日期: 2023-09-27 18:22:19
我正在使用SqlFileStream
将我的(大)对象存储在SQL Server上(在varbinary(max)
列中),但我真的无法随心所欲地使用它。我一直在努力寻找一些专门用于序列化和存储(而不仅仅是从磁盘读取文件以进行存储)的文章,以及如何最有效地做到这一点。是否有一些"隐藏"的最佳实践文章我还没有找到?或者有人有一个很好的例子来说明如何做到这一点吗?
我的主要来源是使用带有C#的SqlFileStream访问SQL Server FILESTREAM数据
编辑:
添加了示例代码,其中对象DataObject
必须使用文件流存储在SQL Server表中。我希望有可能将我的对象流式传输到数据库中,但我目前不知道如何以最佳方式实现这一点,我需要对对象做些什么才能流式传输它,并记住对象可以>1GB,其中有非常复杂的结构。
新编辑:我已经用包含很少数据的数据结构对其进行了测试<300kb并且没有问题。然后我在想,这是缓冲区问题还是类似的问题?
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();
}
}
}
}
我尝试按如下方式序列化对象,但收到一个IOException
错误,上面写着"句柄无效":
using (var dest = new SqlFileStream(serverPath, serverTxn, FileAccess.Write))
{
var formatter = new BinaryFormatter();
formatter.Serialize(dest, data);
dest.Close();
}
我发现了问题。问题是内建序列化程序无法处理大型数据对象,而是使用protobuf-net。