C# ASP.NET 核心构建动态表单
C# ASP.NET Core building dynamic forms
我想实现类似于 SharePoint online 的功能,即列表功能。我想创建动态列表添加新列等。用户可以填写表格并保存数据。
瓶颈是数据库,我很难理解应该如何构建它。
我正在考虑创建动态 SQL 服务器 table、列等,但这也许不是好的方法。有人可以建议数据库应该是什么样子吗?
我正在考虑创建一个名为 Lists
的 table 并在其中存储 List 属性。然后是与另一个名为 Fields
的 table 的多对多关系,我可以在其中存储与特定表单相关的所有字段。多对多关系,因为某些字段对于所有表单都是通用的,例如:Id、CreatedBy、Created、Modified、ModifiedBy 等。现在困难的部分来了。我应该在哪里存储实际数据?我是否应该创建另一个名为 FormData
的 table 并将数据存储在其中?它与Lists
和Fields
tables应该有什么关系?
我会像下面的伪SQL(table 粗体名称)构造它:
列表:
Id int
Name nvarchar(255) -- list name
CreatedBy, Created, Modified, ModifiedBy (audit for the List creation/changes)
列表字段:
Id int
ListId int -- foreign key to associated list
Name nvarchar(255) -- column name
DataType nvarchar(3) -- abbreviation of data type - string, integer, float, bool etc.
Sort int -- column order
CreatedBy, Created, Modified, ModifiedBy (audit for List Field creation/changes)
这定义了列表本身。
现在当用户输入数据时...
ListEntries:(对输入的数据进行分组 - 如果这些是 table 中的列,则每行一条记录,或者输入数据的单个记录表格)
Id int
ListId int -- foreign key to associated list
CreatedBy, Created, Modified, ModifiedBy (audit for Data creation/changes)
ListValues:(每个字段中输入的实际数据)
Id int
ListEntryId int -- foreign key to the associated group of values
ListFieldId int -- foreign key to associated field
Value nvarchar(max) -- data (stored as text regardless of whether text or not - it could be int, double etc.)
就我个人而言,我不会尝试回收公共字段。在每个 table 上都有审计字段可以很好地跟踪更改(如果需要),并且在查看记录时很容易理解。我没有审计单个值,因为通常将更改作为一个集合进行跟踪就足够了(通过 ListEntries
)。当然,如果需要的话,这里也可以进行审计。
NoSql 方法似乎是一种简单的方法。如果您仅将数据库视为不应该包含任何 "business" 逻辑的 IO 设备,那么内存成本和内存 reading/writng 时间 (SSD) 变得更低这一事实 - 您几乎没有更多选择你的问题。
例如,您可以将字段的集合保存在一个对象中
{
"key": "form1",
"fields" : [ "Id", "CreatedAt" ]
}
基于该对象,您可以生成包含已创建字段列表或表单的视图。
您可以为视图生成和数据处理所需的更多数据的字段引入自己的 "object"。
{
"key": "form1",
"fields" : [
{ "Name": "Id", "Type": "string" },
{ "Name" "CreatedAt", "Type": "DateTime" }
]
}
实际数据也可以保存在一个对象中
{
"formKey": "form1",
"Name": "FirstName LastName",
"CreatedAt": "2017-04-23T18:25:43.511Z"
}
在客户端,此数据可以轻松保存为 json 对象并发送到服务器。
在服务器端,您可以将该对象反序列化为 Dictionary<string, object>
并以动态方式处理它
var formEntity = JsonConvert.DeserializeObject<Dictionary<string, object>>(requestBody);
var name = formEntity["Name"].ToString();
如果你紧紧依附于关系数据库,你可以在 NVARCHAR 列和一个标识列中保存 "raw json"。
对于处理数据,您可以将其反序列化为 Dictionary<string, object>
.
使用字段对象 { "Name" "CreatedAt", "Type": "DateTime" }
,您可以将值转换为正确验证和处理的预期类型。
您将能够根据动态字段搜索数据以创建动态报告,用户可以在其中创建自己的报告。
由于字段结构不是动态的,您可以以关系方式保存表单和字段结构。以下是我对 sql 服务器数据库的建议。
CREATE TABLE Forms (
Id INT IDENTITY(1,1) NOT NULL
)
CREATE TABLE Field(
Id INT IDENTITY(1,1) NOT NULL,
Name NVARCHAR(30) NOT NULL,
TypeName NVARCHAR(30) NOT NULL, -- Or INT -> can represent SqlDbType enum in c#
)
-- many to many relation of Form and Fields
CREATE TABLE FormFields (
FormId INT NOT NULL,
FieldId INT NOT NULL,
PRIMARY KEY (FormId, FieldId)
)
-- because data is "dynamic" it should be saved as string (json format)
CREATE TABLE FormData(
Id INT IDENTITY(1,1) NOT NULL,
FormId INT NOT NULL,
Data NVARCHAR(MAX) NOT NULL, -- json format
)
并考虑使用 Microsoft 版本的 NoSql - DocumentDB
我想实现类似于 SharePoint online 的功能,即列表功能。我想创建动态列表添加新列等。用户可以填写表格并保存数据。
瓶颈是数据库,我很难理解应该如何构建它。
我正在考虑创建动态 SQL 服务器 table、列等,但这也许不是好的方法。有人可以建议数据库应该是什么样子吗?
我正在考虑创建一个名为 Lists
的 table 并在其中存储 List 属性。然后是与另一个名为 Fields
的 table 的多对多关系,我可以在其中存储与特定表单相关的所有字段。多对多关系,因为某些字段对于所有表单都是通用的,例如:Id、CreatedBy、Created、Modified、ModifiedBy 等。现在困难的部分来了。我应该在哪里存储实际数据?我是否应该创建另一个名为 FormData
的 table 并将数据存储在其中?它与Lists
和Fields
tables应该有什么关系?
我会像下面的伪SQL(table 粗体名称)构造它:
列表:
Id int
Name nvarchar(255) -- list name
CreatedBy, Created, Modified, ModifiedBy (audit for the List creation/changes)
列表字段:
Id int
ListId int -- foreign key to associated list
Name nvarchar(255) -- column name
DataType nvarchar(3) -- abbreviation of data type - string, integer, float, bool etc.
Sort int -- column order
CreatedBy, Created, Modified, ModifiedBy (audit for List Field creation/changes)
这定义了列表本身。
现在当用户输入数据时...
ListEntries:(对输入的数据进行分组 - 如果这些是 table 中的列,则每行一条记录,或者输入数据的单个记录表格)
Id int
ListId int -- foreign key to associated list
CreatedBy, Created, Modified, ModifiedBy (audit for Data creation/changes)
ListValues:(每个字段中输入的实际数据)
Id int
ListEntryId int -- foreign key to the associated group of values
ListFieldId int -- foreign key to associated field
Value nvarchar(max) -- data (stored as text regardless of whether text or not - it could be int, double etc.)
就我个人而言,我不会尝试回收公共字段。在每个 table 上都有审计字段可以很好地跟踪更改(如果需要),并且在查看记录时很容易理解。我没有审计单个值,因为通常将更改作为一个集合进行跟踪就足够了(通过 ListEntries
)。当然,如果需要的话,这里也可以进行审计。
NoSql 方法似乎是一种简单的方法。如果您仅将数据库视为不应该包含任何 "business" 逻辑的 IO 设备,那么内存成本和内存 reading/writng 时间 (SSD) 变得更低这一事实 - 您几乎没有更多选择你的问题。
例如,您可以将字段的集合保存在一个对象中
{
"key": "form1",
"fields" : [ "Id", "CreatedAt" ]
}
基于该对象,您可以生成包含已创建字段列表或表单的视图。 您可以为视图生成和数据处理所需的更多数据的字段引入自己的 "object"。
{
"key": "form1",
"fields" : [
{ "Name": "Id", "Type": "string" },
{ "Name" "CreatedAt", "Type": "DateTime" }
]
}
实际数据也可以保存在一个对象中
{
"formKey": "form1",
"Name": "FirstName LastName",
"CreatedAt": "2017-04-23T18:25:43.511Z"
}
在客户端,此数据可以轻松保存为 json 对象并发送到服务器。
在服务器端,您可以将该对象反序列化为 Dictionary<string, object>
并以动态方式处理它
var formEntity = JsonConvert.DeserializeObject<Dictionary<string, object>>(requestBody);
var name = formEntity["Name"].ToString();
如果你紧紧依附于关系数据库,你可以在 NVARCHAR 列和一个标识列中保存 "raw json"。
对于处理数据,您可以将其反序列化为 Dictionary<string, object>
.
使用字段对象 { "Name" "CreatedAt", "Type": "DateTime" }
,您可以将值转换为正确验证和处理的预期类型。
您将能够根据动态字段搜索数据以创建动态报告,用户可以在其中创建自己的报告。
由于字段结构不是动态的,您可以以关系方式保存表单和字段结构。以下是我对 sql 服务器数据库的建议。
CREATE TABLE Forms (
Id INT IDENTITY(1,1) NOT NULL
)
CREATE TABLE Field(
Id INT IDENTITY(1,1) NOT NULL,
Name NVARCHAR(30) NOT NULL,
TypeName NVARCHAR(30) NOT NULL, -- Or INT -> can represent SqlDbType enum in c#
)
-- many to many relation of Form and Fields
CREATE TABLE FormFields (
FormId INT NOT NULL,
FieldId INT NOT NULL,
PRIMARY KEY (FormId, FieldId)
)
-- because data is "dynamic" it should be saved as string (json format)
CREATE TABLE FormData(
Id INT IDENTITY(1,1) NOT NULL,
FormId INT NOT NULL,
Data NVARCHAR(MAX) NOT NULL, -- json format
)
并考虑使用 Microsoft 版本的 NoSql - DocumentDB