简体   繁体   中英

How to store a c# object with arrays in a database?

I'm currently developing a software with C# and want it to store the data in a database. My problem is that i'm looking for the best approach to store the data of an object that contains two arrays. The objects in the array look exactly the same but they got a different meaning.

As an information: The data of the objects in the data is changing regularly.

For example i got the following two classe:

public class ObjectA
{
    public string Text { get; set; }
    public int Value { get; set; }
}

public class ObjectB
{
    public string Text { get; set; }
    public int Value { get; set; }
}

public class ObjectC
{
    public string Name { get; set; }
    public List<ObjectA> DetailsA { get; set; }
    public List<ObjectB> DetailsB { get; set; }
}

Please note that i currently got over 24000 objects from ObjectC. The amount of objects that each array of those objects contains can vary quite a lot (up to 200 and maybe more in the future). Could this lead to any problems with the maximum row count if i use one of the solutions?

I got the following two ideas of how the database shema could look like:

  1. All attributes in one table.

    Create a coloumn for each attribute of ObjectA and ObjectB so that i can store each object in the array in one row.

     CREATE TABLE `data` ( `data_id` INT NOT NULL, `name_a` NVARCHAR(50) NOT NULL, `text_a` NVARCHAR(100) NOT NULL, `name_b` NVARCHAR(50) NOT NULL, `text_b` NVARCHAR(100) NOT NULL, `value` INT NOT NULL, PRIMARY KEY (`data_id`) ) 

    In this case i would store the value of name redundantly.

  2. Creating a foreign key in the table for ObjectA

    By doing this i could avoid storing the data from ObjectC redundantly while having to use joins when querying the data.

     CREATE TABLE `data` ( `data_id` INT NOT NULL AUTO_INCREMENT, `name` NVARCHAR(50) NOT NULL, PRIMARY KEY (`data_id`) ) CREATE TABLE `details_a` ( `a_id` INT NOT NULL AUTO_INCREMENT, `text` NVARCHAR(100) NOT NULL, `value` INT NOT NULL, `data_fk` INT NOT NULL, PRIMARY KEY (`a_id`) ) CREATE TABLE `details_b` ( `b_id` INT NOT NULL AUTO_INCREMENT, `text` NVARCHAR(100) NOT NULL, `value` INT NOT NULL, `data_fk` INT NOT NULL, PRIMARY KEY (`b_id`) ) 

Also, would it be better to create a new row in the database for each time the data of the arrays has changed, or should I change the existing data?

Edit: Added some information about the amount of objects (right below the c# example).

(moved from comment to answer, got too long)

Approach 1 does not work with lists of As or Bs btw - you need at least your 2nd version with fks.

Using joins is good, database normalization is good as well. It partitions your data and allows the DB to optimize queries more better.

As a third way you could use a descriminator-column and store A and B in the same dbtable - the discriminator tells you if its a A or a B.

CREATE TABLE `details_ab` (
  `a_id`        INT            NOT NULL    AUTO_INCREMENT,
  `text`        NVARCHAR(100)  NOT NULL,
  `value`       INT            NOT NULL,
  'isA'         BIT            NOT NULL,   -- True == A else B 
  `data_fk`     INT            NOT NULL,
  PRIMARY KEY (`a_id`)
)

The normal/lazy approach is to use / configure an orm mapper to do this for you so you can treat your DB as C# objects and let the details be handled by the orm mapper (google EntityFramework, Hibernate, code-first, data-first, fe here: msdn.microsoft.com/en-us/library/jj200620(v=vs.113).aspx ).


As for the insert or update - it depends. If you have to (legally fe or for insurance) have to have the complete train of data in your DB you could use a table and ever only insert - and a view on top, that diplays the "newest" version of a dataitem.

ie every row has a ID and you have a "BusinessID" that marks "an object" uniquely for you - you insert it the first time, then you modify it: this inserts it with a new DB-Id and the same "BusinessID". You create a view on the table that only shows the highest DB-ID of each BusinessID (assuming integer DB-Ids). You have the whole history in your table, but your application "normally" only sees the view, but maybe admins might get access to the whole table instead of the view ... etc.

Creating the table structure with foreign keys is probably the best solution, and it would be the most commonly implemented. That said, I know needs can vary based on usage case, so here's one possible alternative.

Depending on the usage and the size, I've found it helpful to store objects and variables as XML serialized equivalents in the DB. If you just need it for persistent storage, that's the simplest method and then you could save versioning with a simple table holding a timestamp and the XML object. In a pinch, you can even query your XML objects with SQL to access the data or migrate the storage method if needs change later. I use this method for storing dictionary style data with different data types in a single table for quick access to environmental variables.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM