序列化数据库列 returns 只是文本字段的一部分

Serialized db Column returns only part of a text field

我目前有一个包含两个 TEXT 列的 table。其中一列是使用 Protobuf-net 的序列化对象,似乎可以插入到 table 中(在记事本中检查了 sqlite 文件)。我的问题是当我检索这个 TEXT 项目时,它只有 returns TEXT 的前半部分!

怎么会这样?

我的代码:

public void save(SQLiteConnection m_dbConnection, Day day)
{
  using (MemoryStream stream = new MemoryStream())
  {
    Serializer.Serialize<Day>(stream, day);


    stream.Position = 0;
    StreamReader sr = new StreamReader(stream);
    string data = sr.ReadToEnd();
    string sql = "INSERT INTO mytable (date, data) VALUES (@date, @data)";
    SQLiteCommand command = new SQLiteCommand(sql, m_dbConnection);
    command.CommandType = System.Data.CommandType.Text;
    command.Parameters.Add(new SQLiteParameter("@date", day.getSqlDate()));
    command.Parameters.Add(new SQLiteParameter("@data", data));
    command.ExecuteNonQuery();
  }
}

public Day retrieve(SQLiteConnection m_dbConnection)
{
  string sql = "SELECT * FROM mytable ORDER BY date desc";
  SQLiteCommand command = new SQLiteCommand(sql, m_dbConnection);
  SQLiteDataReader reader = command.ExecuteReader();

  string str = "";
  while (reader.Read())
  {
    //HERE: Only first half of the serialized object
    str = reader["data"].ToString();
    using (Stream stream = GenerateStreamFromString(str))
    {
      return Serializer.Deserialize<Day>(stream);
    }
  }
  return null;
}

public Stream GenerateStreamFromString(string s)
{
  MemoryStream stream = new MemoryStream();
  StreamWriter writer = new StreamWriter(stream);
  writer.Write(s);
  writer.Flush();
  stream.Position = 0;
  return stream;
}

编辑:感谢@Hari Nair,我发现它在某个字符处中断。这是字符 ,但我不知道如何清理此字符串以使其 SQL 安全。有什么想法吗?

注意:我试过替换 \n 和 \r\n 但没有成功,无法弄清楚字符是什么。

序列化程序的输出是二进制的。我不知道你使用的是什么列类型,但如果它是文本,它可能会在二进制数据上咳嗽也就不足为奇了。如果二进制数据包含 NUL (ASCII 0),.NET 中的几乎所有内容都会将其视为字符串终止字符,因此会被截断。我敢打赌,如果您查看 char 数组,您会在它停止的地方看到一个 0

您可以将列类型更改为适合存储二进制数据的类型,或将输出数据编码为类似 Base64 字符串的类型:

你没有语言标签,所以这是VB,如果你需要的话,我会把它修改成C#:

' test string
Dim strFoo = "this is a string"
Dim strB64 As String = ""

Using ms As New MemoryStream()
    ms.Position = 0
    Serializer.Serialize(Of String)(ms, strFoo)

    ' convert binary output to character string
    strB64 = Convert.ToBase64String(ms.ToArray())
End Using

' what a Base64 looks like
Console.WriteLine("Encoded data: {0}", strB64)

' simple test to check the round trip (and what you'll need
' to do when getting the data from the DB):
Dim newFoo As String = ""
Using ms As New MemoryStream(Convert.FromBase64String(strB64))

    newFoo = Serializer.Deserialize(Of String)(ms)
    Console.WriteLine(newFoo)
End Using

输出:

Encoded data: ChB0aGlzIGlzIGEgc3RyaW5n
this is a string