简体   繁体   中英

Forming a Relationship between DB Tables (C#)

I have two tables in my database: category_table and subcategory_table.

Category table has the following columns: id (int, PK), Category (varchar) Subcategory table has the following columns: id (int, PK), Category (int), Subcategory (varchar)

I'm trying to make a form where a user can add/delete both categories and subcategories. There are two comboboxs (where the user can see the current categories. Subcategories can only be seen if their respective category is selected from the first combobox).

The issue I'm having is relating the category_table (id) Primary Key, to the subcategory_table (Category); so that whatever Category is selected in the first combobox, when a Subcategory is added, the (id) of that Category from category_table gets assigned to the (Category) column in subcategory_table .

I understand that Foreign Key can be used; however, I don't know HOW in this situation.

Adding a Category:

    //ADD CATEGORY
    private void addcat_Click(object sender, EventArgs e)
    {
        using (var sqlcmd = new SqlCommand("INSERT INTO category_table (Category) VALUES(@cat);", sqlconnection))
        {
            sqlcmd.Parameters.AddWithValue("@cat", this.cat_txtbx.Text);
            sqlcmd.ExecuteNonQuery();
        }

        this.DialogResult = DialogResult.OK;
        this.Close();
    }

Adding a Subcategory:

    //ADD SUBCATEGORY
    private void addsubcat_Click(object sender, EventArgs e)
    {
        if (string.IsNullOrEmpty(combobox1.Text))
        {
            MessageBox.Show("You must select a category in which to add a subcategory.", "Invalid Operation: Data Missing", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }
        else
        {
            using (var sqlcmd = new SqlCommand("INSERT INTO subcategory_table (Subcategory) VALUES(@subcat);", sqlconnection))
            {
                sqlcmd.Parameters.AddWithValue("@subcat", this.subcat_txtbx.Text);
                sqlcmd.ExecuteNonQuery();
            }
        }
        this.DialogResult = DialogResult.OK;
        this.Close();
    }

If I understand what you want to accomplish, why not structure your database tables like so:

Category:
·categoryId int AUTO_INCREMENT (PRIMARY KEY)
·name varchar(255)

CategoryRelationship:
·id int AUTO_INCREMENT (PRIMARY KEY)
·categoryId int
·parentCategoryId int

This way, all categories (parent categories, solo categories, child or subcategories) will reside in the Category table, and any/all relationships between them are identified in the CategoryRelationship table.

For example, let's say I have six categories: Animal, Vegetable, Mineral, Cat, Tomato, and Sandstone. They would all be stored in the Category table, like so:

1  'Animal'
2  'Vegetable'
3  'Mineral'
4  'Cat'
5  'Tomato'
6  'Sandstone'

Now I want to keep track of the fact that Tomato is a subcategory of Vegetable, and Cat is a subcategory of Animal, etc, all in the CategoryRelationship table:

1  4  1    // Cat (4) is a subcategory of Animal (1)
2  5  2    // Tomato (5) is a subcategory of Vegetable (2)
3  6  3    // Sandstone (6) is a subcategory of Mineral (3)

As an added bonus, a given category can belong to multiple parent categories, thus eliminating duplication:

1  4  1    // Cat (4) is a subcategory of Animal (1)
2  5  2
3  6  3
4  4  7    // Cat (4) is also a subcategory of Feline (7)

Or, a given category can have multiple subcategories:

1  4  1    // Cat (4) is a subcategory of Animal (1)
2  5  2
3  6  3
4  4  7    
5  8  1    // Dog (8) is a subcategory of Animal (1)
6  9  1    // Horse (9) is a subcategory of Animal (1)

Does that help?

Taking exactly the code you have in your add subcategory method, what you need in order to create that foreign key relationship is added:

//ADD SUBCATEGORY
private void addsubcat_Click(object sender, EventArgs e)
{
    if (string.IsNullOrEmpty(combobox1.Text))
    {
        MessageBox.Show("You must select a category in which to add a subcategory.", "Invalid Operation: Data Missing", MessageBoxButtons.OK, MessageBoxIcon.Error);
    }
    else
    {
        using (var sqlcmd = new SqlCommand("INSERT INTO subcategory_table (Category, Subcategory) VALUES(@category, @subcat);", sqlconnection))
        {
            // Added this next line, and the corresponding parts in the INSERT statement above.
            sqlcmd.Parameters.AddWithValue("@category", this.combobox1.SelectedValue); 
            sqlcmd.Parameters.AddWithValue("@subcat", this.subcat_txtbx.Text);
            sqlcmd.ExecuteNonQuery();
        }
    }
    this.DialogResult = DialogResult.OK;
    this.Close();
}

-- edit for more information --

I would recommend renaming the combobox1 to something meaningful, like "categories" or something that makes sense for your purpose.

Also, I notice that there is not an enforced foreign key relationship, because you said that null values are being added. The way you have presented what you are trying to accomplish, I am taking away from it that there is Category and Subcategory, but no more levels. If there are more levels, then @mycargus has provided a good alternative to data structure. If there is just those two levels, it looks like a Subcategory requires having a main "Category."

I would recommend having that foreign key relationship enforced on the database side to prevent null values, and ids that do not exist in the "category_table"

Write a stored procedure, which

step 1. Selects the "category id" based on the selected category from the drop down

step 2. and then write the insert into the subcategory table with the category id obtained in step 1.

And call the stored procedure from your addsubcat_Click method.

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