将C#数据结构存储到SQL数据库中

我是ASP.NET和SQL服务器的新手,所以请原谅我的无知……

如果我在C#中有一个数据结构(例如,让我们说,存储一些字符串的向量),是否可以像在SQL表中那样存储向量的内容? 我想这样做,以便尽快将数据转换回矢量forms,而不必逐个元素地构造它。 几乎就像将二进制数据写入文件然后读取它并将其复制到C中的已分配结构。

我在SQL Server 2008上创建了一个表,其中一个字段被定义为VARBINARY(MAX)。 我以为我会从那开始。

有人可以向我展示一个例子,说明如何在该字段中存储和检索10个字符串的向量? 这甚至可能(我想不出为什么不)?

谢谢!

首先,有一条简单的创建关系结构并将对象映射到数据库中的字段的明显路径。

其次,如果您有一个可序列化的对象,则可以将其存储在SQL Server中。 我偶尔也这样做了,并使用SQL Server中的Text数据类型来存储XML。

意见:我更喜欢将序列化对象存储为XML而不是二进制数据。 为什么? 因为您实际上可以读取其中的内容(用于调试),并且在SQL Server中,您可以使用XQuery从序列化对象中选择数据。 根据我的经验,与使数据更容易调试并且可以以伪相关方式使用相比,使用二进制数据的性能提升将是不值得的。 看看SQL Server的XQueryfunction 。 即使您不打算立即使用它,也没有理由让自己陷入困境。

您可以使用NetDataContractSerializer查看一些示例。

我相信你所谓的向量是C#中的List <>。 看看System.Collections.Generic。 您可以使用NetDataContractSerializer序列化3个字符串的List,如:

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Runtime.Serialization; using System.IO; namespace SerializeThingy { class Program { static void Main(string[] args) { List myList = new List(); myList.Add("One"); myList.Add("Two"); myList.Add("Three"); NetDataContractSerializer serializer = new NetDataContractSerializer(); MemoryStream stream = new MemoryStream(); serializer.Serialize(stream, myList); stream.Position = 0; Console.WriteLine(ASCIIEncoding.ASCII.GetString(stream.ToArray())); List myList2 = (List)serializer.Deserialize(stream); Console.WriteLine(myList2[0]); Console.ReadKey(); } } } 

这个例子只是序列化一个列表,将序列化输出到控制台,然后certificate它在反面是正确的水合。 我想你可以从这里看到,你可以将内存流转储到字符串中并将其写入数据库,或者使用另一种流类型而不是内存流来执行此操作。

请记住引用System.Runtime.Serialization来访问NetDataContractSerializer。

 [Serializable] public struct Vector3 { public double x, y, z; } class Program { static void Main(string[] args) { Vector3 vector = new Vector3(); vector.x = 1; vector.y = 2; vector.z = 3; MemoryStream memoryStream = new MemoryStream(); BinaryFormatter binaryFormatter = new BinaryFormatter(); binaryFormatter.Serialize(memoryStream, vector); string str = System.Convert.ToBase64String(memoryStream.ToArray()); //Store str into the database } } 

假设对象标有[Serializable]或实现ISerializableBinaryFormatter类提供了一种简单的方法。

如果没有,您正在查看(非平凡的)自定义代码。

如果你要这样做(我想这在技术上是可行的 ),你也可以使用平面文件:再也不用使用关系数据库了。

这是通用列表的另一种更通用的方法。 请注意,列表中存储的实际类型也必须是可序列化的

 using System.Runtime.Serialization.Formatters.Binary; using System.IO; using System.Data.SqlClient; using System.Runtime.Serialization; public byte[] SerializeList(List list) { MemoryStream ms = new MemoryStream(); BinaryFormatter bf = new BinaryFormatter(); bf.Serialize(ms, list); ms.Position = 0; byte[] serializedList = new byte[ms.Length]; ms.Read(serializedList, 0, (int)ms.Length); ms.Close(); return serializedList; } public List DeserializeList(byte[] data) { try { MemoryStream ms = new MemoryStream(); ms.Write(data, 0, data.Length); ms.Position = 0; BinaryFormatter bf = new BinaryFormatter(); List list = bf.Deserialize(ms) as List; return list; } catch (SerializationException ex) { // Handle deserialization problems here. Debug.WriteLine(ex.ToString()); return null; } } 

然后在客户端代码中:

 List stringList = new List() { "January", "February", "March" }; byte[] data = SerializeList(stringList); 

存储/检索此字节数组的一种基本方法是使用简单的SQLClient对象:

 SqlParameter param = new SqlParameter("columnName", SqlDbType.Binary, data.Length); param.Value = data; etc... 

有理由保持灵活性。 不应允许数据库结构的规则或指南妨碍创造力。 鉴于这里的第一个线程,我可以看到用于存储序列化和约束列的混合方法。 通过让人们保持开放的可能性,可以大大改善许多应用程序。

无论如何,我对新事物的看法表示赞赏。 保持新鲜感……

我对关系数据库比c#有更多的经验,但二进制序列化是一种可接受的方式,因为它允许将整个对象的状态保存到数据库中。 XML序列化几乎相同,但不允许使用generics类型。