就集合中的类型而言,.Net 类型和 SQL 类型之间存在相当一对一的映射:SQL Server Data Type Mappings。您主要需要担心字符串字段:
- 它们是否总是 ASCII 值 (0 - 255)?然后使用
VARCHAR。如果它们可能包含非 ASCII / UCS-2 字符,请使用 NVARCHAR。
- 它们可能的最大长度是多少?
当然,有时您可能希望在数据库中使用稍微不同的数字类型。主要原因是如果在应用程序端选择了int,因为它比Int16 和byte 处理起来“更容易”(或者我被告知),但值永远不会超过32,767 或255,那么您很可能应该分别使用SMALLINT 或TINYINT。 int 和 byte 在应用层内存方面的差异可能很小,但它确实对物理存储有影响,尤其是当行数增加时。如果不清楚,“影响”意味着减慢查询速度,有时当您需要购买更多 SAN 空间时会花费更多钱。但是,我说“最有可能使用SMALLINT 或TINYINT”的原因是因为如果您有企业版并启用了行压缩或页面压缩,那么这些值将存储在它们将适合的最小数据类型。
就从数据库中检索数据而言,这只是一个简单的SELECT。
就存储这些数据而言(至少在有效地执行数据方面),嗯,这更有趣:)。将字段列表传输到 SQL Server 的一种好方法是使用表值参数 (TVP)。这些是在 SQL Server 2008 中引入的。我在这个答案中发布了一个代码示例(C# 和 T-SQL),这里有一个非常相似的问题:Pass Dictionary<string,int> to Stored Procedure T-SQL。关于该问题还有另一个 TVP 示例(已接受的答案),但它没有使用 IEnumerable<SqlDataRecord>,而是使用了一个不必要的集合副本 DataTable。
编辑:
关于指定要持久化的实际数据的问题的最新更新,应将其存储在类似于以下内容的表中:
UserID INT NOT NULL,
TemplateIndex INT NOT NULL,
TemplateValue VARCHAR(100) NOT NULL
PRIMARY KEY 应该是 (UserID, TemplateIndex),因为这是唯一的组合。不需要(至少在给定信息的情况下)不需要 IDENTITY 字段。
TemplateIndex 和 TemplateValue 字段将在 TVP 中传递,如我对上面链接的问题的回答所示。 UserID 将作为第二个SqlParameter 自行发送。在存储过程中,你会做类似的事情:
INSERT INTO SchemaName.TableName (UserID, TemplateIndex, TemplateName)
SELECT @UserID,
tmp.TemplateIndex,
tmp.TemplateName
FROM @ImportTable tmp;
并且只是明确说明,除非有一个 非常 这样做的特定原因(这需要包括从不,永远需要在任何查询中使用此数据,以便此数据实际上只是一个文档,在查询中不比 PDF 或图像更有用),那么您不应该将其序列化为任何格式。尽管如果您愿意这样做,XML 是比 JSON 更好的选择,至少对于 SQL Server 来说是这样,因为 SQL Server 中内置了与 XML 数据交互的支持,但对于 JSON 则没有那么多。