C#:如何在SQL Server中存储任意对象?

时间:2009-07-13 08:35:47

标签: c# sql-server database-design serialization data-structures

假设您有各种任意类型的对象,您希望将它们存储在表的键+值类型中。键可以是例如int,string或guid。价值是什么?字符串,二进制或其他什么?

您将如何存储和加载对象?我会想某种序列化,但是那种什么?


我现在有一个解决方案,我有一个使用这两种方法的课程:

public T Get<T>(string key)

public void Set<T>(string key, T value)

在数据库中,我有一个包含字符串列和二进制列的表。然后我使用BinaryFormatter序列化和反序列化值,并使用Linq2Sql将二进制结果放入数据库表中。但这是一个很好的解决方案吗?目前我只敢用整数和字符串这样的简单值来尝试这个。 BinaryFormatter和序列化如何与更复杂的类型(如结构和类)一起工作?特别是如果例如值包含数组或列表之类的东西。

任何指针?


目前我将使用它来存储各种最后选择或输入类型的值。虽然它们可能并不总是必须打字。例如,它可能是从列表中选择值。重点是它们几乎只是用户的便利,所以不是非常关键的数据。

3 个答案:

答案 0 :(得分:6)

如果您可以将自己限制为易于映射到SQL类型的特定类型,我很想将它们保存在表格的不同列中,确保您只填写其中一个。这样您就可以阅读数据库中的数据,使ad-hoc查询更容易。这也意味着你不会永远陷入.NET。

有许多不同的序列化选项可用。核心框架当然是BinaryFormatterXmlSerializer; XML更便携,但代价是空间。我相信它也不那么彻底可定制。

有第三方序列化技术,例如ThriftProtocol Buffers。就可以序列化的内容而言,这些将更具限制性,但更具便携性。 (免责声明:我的20%项目是协议缓冲区的C# port,所以我不完全不偏不倚。)

您还应该考虑版本控制 - 如果您更改了序列化/反序列化的数据结构,您希望发生什么?也许你不需要能够阅读“旧”记录,也许你可以。也许您需要旧代码才能读取“新”记录 - 或者可能不是。

您的技术选择应该完全由需求驱动。你试图做的越普遍,它就会变得越复杂 - 所以在你尝试提出解决方案之前要弄清楚你真正需要的东西。

答案 1 :(得分:1)

当我们完成这类事情时,我们在C#中将数据保存在字节数组中,并将其存储在SQL Server的varbinary(max)列中。

编辑根据评论

您可以尝试在您的类上创建一个属性值字段的字节数组。

答案 2 :(得分:0)

通常我会使用特定列来表示某种值。

例如

  • GuidUNIQUEIDENTIFIER
  • intdecimalbyte等数字:DECIMAL
  • stringNVARCHAR
  • DateTimeDATETIME

我正在使用NHibernate,在那里很容易为每个特定类型创建一个子类并将它们映射到同一个表,每个表都使用特定字段作为其特定值。我得到一张这样的桌子:

create table dbo.Value (
  Name NVARCHAR(80) not null,
  Type NVARCHAR(6) not null,
  TextValue NVARCHAR(500) null,
  GuidValue UNIQUEIDENTIFIER null,
  NumericValue DECIMAL(36, 18) null,
  DateTimeValue DATETIME null
)

列类型为“TEXT”,“GUID”,“NUMBER”或“DATE”。这一切都是由NHibernate完成的,但没有它就可以很容易地使用和操作。

此外,您可以使用NH any类型作为值(存储主键和实体名称)来存储对另一个实体的引用。