Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# ASP.NET Core building dynamic forms

I want to implement something similar like SharePoint online does and that is the list functionality. I want to create dynamic lists add new columns, etc. The user can fill in the form and save the data.

The bottle neck is the database, I have some hard time understand how this should be built.

I was thinking to create dynamic SQL Server tables, columns, etc, but maybe this is not the good approach. Can somebody advise on how the database should look like?

I was thinking about creating one table called Lists and there store List properties. Then a many to many relation to another table called Fields where I can store all fields related to a specific form. Many to many relation because some fields are common for all forms like: Id, CreatedBy, Created, Modified, ModifiedBy, etc. Now comes the difficult part. Where should I store the actual data? Should I create another table called FormData and store in there the data? And what relation should it have with Lists and Fields tables?

like image 685
user2818430 Avatar asked Apr 27 '17 08:04

user2818430


People also ask

What C is used for?

C programming language is a machine-independent programming language that is mainly used to create many types of applications and operating systems such as Windows, and other complicated programs such as the Oracle database, Git, Python interpreter, and games and is considered a programming foundation in the process of ...

What is the full name of C?

In the real sense it has no meaning or full form. It was developed by Dennis Ritchie and Ken Thompson at AT&T bell Lab. First, they used to call it as B language then later they made some improvement into it and renamed it as C and its superscript as C++ which was invented by Dr.

Is C language easy?

C is a general-purpose language that most programmers learn before moving on to more complex languages. From Unix and Windows to Tic Tac Toe and Photoshop, several of the most commonly used applications today have been built on C. It is easy to learn because: A simple syntax with only 32 keywords.

Is C programming hard?

C is more difficult to learn than JavaScript, but it's a valuable skill to have because most programming languages are actually implemented in C. This is because C is a “machine-level” language. So learning it will teach you how a computer works and will actually make learning new languages in the future easier.


2 Answers

NoSql approach seems to be a simple one. If you think about databases only as IO devices, which shouldn't contain any "business" logic, the fact that memory cost and memory reading/writng time(SSD) become lower - you will have little bid more options for your issue.

For example you can save field's collection in one object

{
    "key": "form1",
    "fields" : [ "Id", "CreatedAt" ]
}

Based on that object you can generate view with list or form of created fields. You can introduce own "object" for field with more data you need for view generation and for data processing.

{
    "key": "form1",
    "fields" : [ 
        { "Name": "Id", "Type": "string" }, 
        { "Name" "CreatedAt", "Type": "DateTime" } 
    ]
}

The actual data can be saved in one object too

{
    "formKey": "form1",
    "Name": "FirstName LastName",
    "CreatedAt": "2017-04-23T18:25:43.511Z"
}

On client side this data can be easily saved as json object and sended to the server.
On server side you can deserialize that object as Dictionary<string, object> and handle it in dynamic way

var formEntity = JsonConvert.DeserializeObject<Dictionary<string, object>>(requestBody);

var name = formEntity["Name"].ToString();

If you tightly attached to the relational database, you can save "raw json" in NVARCHAR column and one identity column.
For processing data you will be able to deserialize it to the Dictionary<string, object>.
With field object { "Name" "CreatedAt", "Type": "DateTime" } you can convert values to the expected types for correct validation and processing.

You will be able to search for data based on dynamic fields ro create dynamic reports, where user can create his own reports.

Because structure of fields not dynamic you can save forms and fields structure in relational way. Below is my suggestion for sql server database.

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
)

And consider to use Microsoft version of NoSql - DocumentDB

like image 85
Fabio Avatar answered Oct 11 '22 08:10

Fabio


I would structure it like the following pseudo-SQL (table names in bold):

Lists:

Id int
Name nvarchar(255)  -- list name
CreatedBy, Created, Modified, ModifiedBy (audit for the List creation/changes)

ListFields:

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)

That defines the lists themselves.

Now when the user enters data...

ListEntries: (groups the data entered - would be a record per row if these are columns in a table, or a single record for data entered into a form)

Id int
ListId int  -- foreign key to associated list
CreatedBy, Created, Modified, ModifiedBy (audit for Data creation/changes)

ListValues: (actual data entered into each field)

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.)

Personally I wouldn't try to recycle common fields. Having the audit fields on each table gives a fine grain to change tracking (if needed) and is easy to follow when looking at the records. I left auditing off the individual values because often it is sufficient to track changes as a collection (via ListEntries). Of course, auditing could exist here too if desired.

like image 42
K Scandrett Avatar answered Oct 11 '22 07:10

K Scandrett