我可以在SQL Server数据库中保存"对象"吗?

Ahm*_*rid 45 c# sql-server ado.net sql-server-2005

我想将对象(任何类型)保存到SQL Server 2005中的数据库中的字段中.是否可能?我是否必须将对象转换为某些内容,例如字节数组,并在检索时将其转换回来?

mar*_*c_s 30

VARBINARY(MAX)如果您愿意,可以在SQL Server中使用字段类型.您可以在其中存储任何类型的对象,最大为2 GB.

要访问它,您可以使用ADO.NET - 如下所示:

object yourMysteryObject = (whatever you like it to be);

MemoryStream memStream = new MemoryStream();
StreamWriter sw = new StreamWriter(memStream);

sw.Write(yourMysteryObject);

SqlCommand sqlCmd = new SqlCommand("INSERT INTO TableName(VarBinaryColumn) VALUES (@VarBinary)", sqlConnection);

sqlCmd.Parameters.Add("@VarBinary", SqlDbType.VarBinary, Int32.MaxValue);

sqlCmd.Parameters["@VarBinary"].Value = memStream.GetBuffer();

sqlCmd.ExecuteNonQuery();
Run Code Online (Sandbox Code Playgroud)

  • 咦?如果你传递sw.Write()一个通用的Object,它只是调用Object的ToString方法!这不会序列化它! (6认同)

Bad*_*aro 24

我会使用JSON将对象转换为字符串,并将其存储在VARCHAR或TEXT字段中.不仅数据以人类可读的格式存储,而且它也可以从不同的语言中读取,因为几乎每种主流语言都有可用的JSON解析器.

我发布的链接有许多语言(包括C#)的几个库的链接,我过去曾经多次使用过这个.


Mar*_*ell 12

正如其他人所说,序列化可能是关键(假设你不想使用ORM将属性存储为表中的列,这似乎更直接).

但有些警告; 一个数据库是:

  • 长期储存
  • 与您的.NET代码无关

因此,您希望使用任何特定于平台或特定于版本的序列化技术.你会经常看到人们提到BinaryFormatter持久性,但这属于上述两个陷阱.如果您更换过平台,或者即使您只是更改了某些属性,您也会被打垮.

您需要一种与实现无关的方法; 最简单的(也保留了人类可读的能力)是xml或json,也许是通过XmlSerializer或Json.NET(存储在a中[n]varchar(max)).如果你不关心人类可读,"协议缓冲区"(快速/二进制)会很好(存储在a中varbinary(max)),并且可用于大多数平台(包括C#/ .NET /等).


Ivo*_*nov 11

如果您使用实体框架(EF),这是一个示例:

using (DbContext db = new DbContext())
{
    // The object that you want to serialize. In this case it is just an empty instance
    YourObject objectToSerialize = new YourObject();
    IFormatter formatter = new BinaryFormatter();
    using (MemoryStream stream = new MemoryStream())
    {
        formatter.Serialize(stream, objectToSerialize);

        // EF model. In one of its properties you store the serialized object
        YourModel modelObject = new YourModel();

        // In your model 'SerializedObject' should be of type byte[]. In the database it should be of type varbinary(MAX)
        modelObject.SerializedObject = stream.ToArray(); 
        db.YourModel.Add(modelObject);
        db.SaveChanges();
    }
}
Run Code Online (Sandbox Code Playgroud)

这是如何反序列化对象:

// De-serialize
IFormatter formatter = new BinaryFormatter();
Stream stream = new MemoryStream(serializedObject);
YourObject deserializedYourObject = (YourObject)formatter.Deserialize(stream);
stream.Close();
Run Code Online (Sandbox Code Playgroud)