[英]Storing C# data structure into a SQL database
我是ASP.NET和SQL服务器的新手,所以请原谅我的无知......
如果我在C#中有一个数据结构(例如,让我们说,存储一些字符串的向量),是否可以像在SQL表中那样存储向量的内容? 我想这样做,以便尽快将数据转换回矢量形式,而不必逐个元素地构造它。 几乎就像将二进制数据写入文件然后读取它并将其复制到C中的已分配结构。
我在SQL Server 2008上创建了一个表,其中一个字段被定义为VARBINARY(MAX)。 我以为我会从那开始。
有人可以告诉我一个例子,我将如何存储和检索10个字符串的向量进出该字段? 这甚至可能(我想不出为什么不)?
谢谢!
首先,有一条简单的创建关系结构并将对象映射到数据库中的字段的明显路径。
其次,如果您有一个可序列化的对象,则可以将其存储在SQL Server中。 我偶尔也这样做了,并使用SQL Server中的Text数据类型来存储XML。
意见:我更喜欢将序列化对象存储为XML而不是二进制数据。 为什么? 因为您实际上可以读取其中的内容(用于调试),并且在SQL Server中,您可以使用XQuery从序列化对象中选择数据。 根据我的经验,与使数据更容易调试并且可以以伪相关方式使用相比,使用二进制数据的性能提升将是不值得的。 看看SQL Server的XQuery功能 。 即使您不打算立即使用它,也没有理由让自己陷入困境。
您可以使用NetDataContractSerializer查看一些示例。
我相信你所谓的向量是C#中的List <>。 看看System.Collections.Generic。 您可以使用NetDataContractSerializer序列化3个字符串的列表,如:
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<string> myList = new List<string>();
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<string> myList2 = (List<string>)serializer.Deserialize(stream);
Console.WriteLine(myList2[0]);
Console.ReadKey();
}
}
}
这个例子只是序列化一个列表,将序列化输出到控制台,然后证明它在反面是正确的水合作用。 我想你可以从这里看到你可以将内存流转储到一个字符串中并将其写入数据库,或使用另一种流类型而不是内存流来执行它。
请记住引用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]
或实现ISerializable
, BinaryFormatter
类提供了一种简单的方法。
如果没有,您正在查看(非平凡的)自定义代码。
如果你要这样做(我想这在技术上是可行的 ),你也可以使用一个平面文件:使用关系数据库是没有意义的。
这是通用列表的另一种更通用的方法。 请注意,存储在列表中的实际类型也必须是可序列化的
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;
using System.Data.SqlClient;
using System.Runtime.Serialization;
public byte[] SerializeList<T>(List<T> 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<T> DeserializeList<T>(byte[] data)
{
try
{
MemoryStream ms = new MemoryStream();
ms.Write(data, 0, data.Length);
ms.Position = 0;
BinaryFormatter bf = new BinaryFormatter();
List<T> list = bf.Deserialize(ms) as List<T>;
return list;
}
catch (SerializationException ex)
{
// Handle deserialization problems here.
Debug.WriteLine(ex.ToString());
return null;
}
}
然后在客户端代码中:
List<string> stringList = new List<string>() { "January", "February", "March" };
byte[] data = SerializeList<string>(stringList);
存储/检索此字节数组的一种基本方法是使用简单的SQLClient对象:
SqlParameter param = new SqlParameter("columnName", SqlDbType.Binary, data.Length);
param.Value = data;
etc...
有理由保持灵活性。 不应允许数据库结构的规则或准则妨碍创造力。 鉴于这里的第一个线程,我可以看到用于存储序列化和约束列的混合方法。 许多应用程序可以通过让人们保持开放的可能性而得到极大改善。
无论如何,我对新事物的看法表示赞赏。 保持新鲜感......
我对关系数据库的经验比c#更多,但二进制序列化是一种可接受的方式,因为它允许将整个对象的状态保存到数据库中。 XML序列化几乎相同,但不允许使用泛型类型。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.