在DB表之间形成关系(C#)

时间:2015-04-23 22:35:03

标签: c# database winforms

我的数据库中有两个表:category_table和subcategory_table。

类别表格包含以下列:id (int, PK), Category (varchar) 子类别表包含以下列:id (int, PK), Category (int), Subcategory (varchar)

我试图创建一个用户可以添加/删除类别和子类别的表单。有两个组合框(用户可以看到当前的类别。只有从第一个组合框中选择它们各自的类别时才能看到子类别。)

我遇到的问题是将category_table(id)主键与subcategory_table(类别)相关联;因此,无论在第一个组合框中选择了哪个类别,当添加子类别时,category_table中该类别的(id)将被分配到subcategory_table中的(类别)列。

据我所知,可以使用外键;但是,在这种情况下,我不知道如何。

添加类别:

    //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();
    }

添加子类别:

    //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();
    }

3 个答案:

答案 0 :(得分:0)

如果我理解你想要完成什么,为什么不这样构建你的数据库表:

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

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

这样,所有类别(父类别,独奏类别,子类别或子类别)都将驻留在Category表中,并且它们之间的任何/所有关系都在CategoryRelationship表中标识。

例如,假设我有六个类别:动物,蔬菜,矿物,猫,番茄和砂岩。它们都将存储在Category表中,如下所示:

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

现在我想跟踪一个事实,即Tomato是VEG的子类别,而Cat是Animal等的子类别,都在CategoryRelationship表中:

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)

作为额外奖励,给定类别可以属于多个父类别,从而消除重复:

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)

或者,给定类别可以有多个子类别:

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)

这有帮助吗?

答案 1 :(得分:0)

准确地使用add子类别方法中的代码,添加了创建该外键关系所需的代码:

//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();
}

- 编辑以获取更多信息 -

我建议将combobox1重命名为有意义的内容,例如“类别”或对您的目的有意义的内容。

另外,我注意到没有强制的外键关系,因为你说正在添加空值。你提出你想要完成什么的方式,我正在消除它有类别和子类别,但没有更多的水平。如果有更多级别,那么@mycargus提供了一个很好的数据结构替代方案。如果只有这两个级别,它看起来像一个子类别需要一个主“类别”。

我建议在数据库端强制执行外键关系以防止空值,以及“category_table”中不存在的ID

答案 2 :(得分:0)

编写存储过程,

步骤1.选择"类别ID"基于下拉列表中选定的类别

步骤2.然后将插入内容写入子类别表中,并在步骤1中获取类别ID。

从addsubcat_Click方法调用存储过程。