我的数据库中有一个表格,用于表示自定义表单中的数据字段。 DataField提供了一些表示它应该用什么样的控件表示,以及它应该采用什么值类型。简化你可以说我在这个表中有2个实体 - Textbox采用任何字符串,Textbox只采用数字。
现在我将不同的值存储在一个单独的表中,引用数据域定义。当类型不同时,在这里存储数据值的最佳方法是什么?
一种可能的解决方案是让FieldValue表为每种可能的值类型保留一个字段。现在这肯定是多余的,但至少我会以正确的形式存储值 - 稍后简化查询。
FieldValue
----------
Id
DataFieldId
IntValue
DoubleValue
BoolValue
DataValue
..
另一种可能性是将所有内容存储为String,并将其转换为查询。我正在使用.Net与NHibernate,我发现至少在这里有一个Projections.Cast可用于演示例如字符串到查询中的int。
无论哪种方式在这两个解决方案中,我都需要知道在执行查询时要使用哪种类型,但我会从DataField中知道,这样就不会有问题了。
反正;我不认为这些解决方案听起来不错。是吗?或者,还有更好的方法?
答案 0 :(得分:1)
没有第三个“魔术”选项:您的具体情况决定了您希望如何继续。
根据我的经验,仅使用字符串的解决方案对应用程序设置等内容有意义。通常,我不需要直接在查询中使用这些数据,因此它不会让我感到困扰,因为它是字符串形式。
我不确定,但似乎是您正在使用自定义属性扩展实体,这听起来您可能希望在某些时候在数据库中进行一些处理。在这种情况下,您可以使用多列方法并仅填充具有正确类型的列。它不会很漂亮,但可能会简化查询。
正如我所说,这取决于你需要运行的查询和类型,你需要什么样的性能等。
答案 1 :(得分:1)
从多租户数据存储中提取想法,您可以使用'Name-Pair' values idea as described on MSDN。我不知何故认为除了提到的特定部分之外,本文将更有用。
实际上,要使其成为可扩展的解决方案,您需要使用元数据表定义自定义表单的数据类型,其中您可以定义要存储的数据的实际类型(例如bool,text,int , 约会时间)。您也可以考虑存储.Net类型,因为这可能会在输入验证等方面为您提供帮助。可能存储的其他详细信息也是您希望它们出现的字段名称。你的自定义表格。使用此方法,您可以根据存储的元数据构建自定义表单。
我已成功使用此方法,效果很好。另外,我们还使用元数据表来定义自定义字段的预期值是否是用户提供的(例如姓名,出生日期)或下拉列表中的预定义系统值(例如,citye,countries列表)。为了支持这一点,我们有一个附加表,其中包含链接回元数据表的列表选项。
答案 2 :(得分:0)
如果你只有2个文本框,用户可以输入值,并且它可以是字符串或数字,你真的需要能够区分int和double,你不能只是存储它all作为合适的数字类型(取决于DB)。这会让你只有2种不同的类型,然后一个可能的解决方案是拥有2个表,每个表一个。
总的来说,每当我看到很难知道什么是数据类型时,我就会开始担心该项目试图成为通用的,这种通用性会变得非常混乱。
答案 3 :(得分:0)
在提出我的观点之前..我会说你可能需要回到ER板。 我想 CustomForm 有很多 Fields ,而且这些 Fields 是不同种类的(文本,数据,甚至是行为和风格),而不是概括概念 Field 可能值得考虑为每种类型的Field创建一个表。例如。 DateField,UserNameField等。这将使值类型恰好是一个具有正确类型的非空列。我还打赌这会简化您的代码(更少的条件来检查,数据库会为您提供所有信息。)
也就是说,您可能无法返回到ER板,或者可能存在进行多列每类型方法的潜在有效理由。以下是这种方法的一些优点和缺点。
优点
缺点
如果您遇到 CustomForm > 字段 - > FieldValue 我建议每个 FieldValue 创建一个表。 e.g。
IntFieldValue
-------------
Id
DataFieldId
Value
DecimalFieldValue
-------------
Id
DataFieldId
Decimal
DateFieldValue
-------------
Id
DataFieldId
Date
通过上述内容,您仍然可以创建一个从上表中选择的视图。可以创建视图以为每个值类型提供一列,并且保证,其中只有一个不是NULL。这也更容易扩展(添加新表,更改视图,但不需要使用新值类型的空值更新任何现有数据)。