I am pretty new with databases, I've been working on a school windows forms .NET project in C# and I came to a problem.
I have a table in a SQL Server database with patients (animals) and I need to add a list (unknown length) of vaccines dosages that each patient has gotten. Each animal will have different length and values in its list of vaccines.
Can someone please tell me how can I store the list in the database column?
So you have a table of
Animals
and a table ofVaccines
You give an Animal a dosage of a Vaccine. To remember which Animal got which dosage, you need a table
VacineDosages
. In this table, you can see which Animal got a Dosage of which Vaccine. You probably want to know on which Date the Animal got the dosage, and maybe the amount of the dosage.There is a one-to-many relation between Animals and VaccineDosages: Every Animal got zero or more VaccineDosages, every VaccineDosage has been given to exactly one Animal
Similarly there is also a one-to-many relation between Vaccines and VaccineDosages: Every Vaccine has been used zero or more times in a VaccineDosage, every VaccineDosage is a Dosage of exactly one Vaccine.
When using a relational database, one-to-many relations are implemented using a foreign key. The item on the "many" side gets a foreign key to the item on the "one" side that it belongs to.
Every VaccineDosage has been used to vaccinate exactly one Animal; the dosage "belongs" to this one Animal, hence it gets a foreign key to this Animal. Similarly, a VaccineDosage belongs to a Vaccine, and thus has a foreign key
Now to add VaccineDosages, you need to know to Which Animal the VaccineDosage was given, and with Which Vaccine. Well, you don't need to know the Animal and Vaccine, only their Ids will do.
So Suppose you have a sequence of VaccineDosages that are not added to the database yet, so they don't have an Id yet.
Or, in C# classes:
Now how to add this list to the database? The method depends on what method you use to communicate with the database:
Of course, as a good programmer you want to hide where and how you save your data: it can be in a database, but maybe you want to do it in an XML file for unit tests, of CSV, Json?
All that users want to know: I want to put items in an object, and later, even after a restart of the computer, I can fetch the items again from the same object.
This "Warehouse" thing, is quite often called a repository:
These methods return the newly created Id of the added item, so later you can fetch them by Id:
You add methods to the repository as needed:
etc.
In your case, you also want a method to add a sequence of VaccineDosages.
Maybe all VaccineDosages are inserted in the same Animal, or on the same date, if that is the case, consider to create overloads:
To make life easy for you, these overloads can call your original version. You probably won't be adding 1000 vaccins per seconds.
The nice thing of the repository is that you hide how the data is saved. For a small project and unit tests you can save it as a CSV file, or XML. Later you can safely change it to save in a database using SQL, You can change the type of database, or the method used to communicate with the DBMS. Users of your repository don't have to change, and thus don't need to be tested again.
LOW Level: SQL with parameters
If you are still learning databases, it is a good idea to start low level, so you get the feeling which code is done "under the hood" when you use higher level methods
When communicating with the database at low level, you create a Database Connection. You ask the connection to create a command, and you fill the command with the SQL text and the parameters. Finally you execute the command.
Usually you don't want to have an open database connection for a longer period of time. You make one procedure that opens and closes the database connection for one action: adding one VaccineDosage, or a fairly small sequence of VaccinedDosages.
If you need to Add a million VaccineDosages to the database in one call, you are talking about bulk usages. This might require a different approach. This is out of scope of your question.
A database connection has a connection string. It depends on which database management system (DBMS) you use, whether you need to provide this connection string or not. If you don't provide it, the application uses the connection string that is provided in file app.config.
To hide which actual DBMS you use, consider to create a factory method that creates the proper database connection for you:
If later you decide to use a different DBMS, you'll only have to change this procedure.
Hide the names of the tables, so you can change them later:
The
using
statements assert that all items are closed and thrown away correctly, as soon as not used anymoreIf you want to add a bunch of VaccineDosages, you can call this method several times. Or a slight optimization, reuse the dbCommand
Of course you could omit using parameters and create one sql text that contains the complete sql command, but that might be dangerous: people could destroy your database. See SQL Injection attack