在DB表之间形成关系(C#)
我的数据库中有两个表:category_表和subcategory_表 类别表有以下列:在DB表之间形成关系(C#),c#,database,winforms,C#,Database,Winforms,我的数据库中有两个表:category_表和subcategory_表 类别表有以下列:id(int,PK)、Category(varchar) 子类别表有以下列:id(int,PK)、Category(int)、Subcategory(varchar) 我正在尝试制作一个表单,用户可以在其中添加/删除类别和子类别。有两个组合框(用户可以在其中查看当前类别。只有从第一个组合框中选择了各自的类别,才能查看子类别) 我遇到的问题是将类别表(id)主键与子类别表(类别)关联起来;因此,无论在第一个组合
id(int,PK)、Category(varchar)
子类别表有以下列:id(int,PK)、Category(int)、Subcategory(varchar)
我正在尝试制作一个表单,用户可以在其中添加/删除类别和子类别。有两个组合框(用户可以在其中查看当前类别。只有从第一个组合框中选择了各自的类别,才能查看子类别)
我遇到的问题是将类别表
(id)主键与子类别表
(类别)关联起来;因此,无论在第一个组合框中选择了什么类别,当添加子类别时,该类别的(id)将从Category\u table
分配到Subcategory\u table
中的(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();
}
添加子类别:
//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();
}
如果我了解您想要完成的任务,为什么不按如下方式构建数据库表:
Category:
·categoryId int AUTO_INCREMENT (PRIMARY KEY)
·name varchar(255)
CategoryRelationship:
·id int AUTO_INCREMENT (PRIMARY KEY)
·categoryId int
·parentCategoryId int
这样,所有类别(父类别、单独类别、子类别或子类别)都将驻留在类别
表中,它们之间的任何/所有关系都将在类别关系
表中标识
例如,假设我有六个类别:动物、蔬菜、矿物质、猫、西红柿和砂岩。它们都将存储在类别
表中,如下所示:
1 'Animal'
2 'Vegetable'
3 'Mineral'
4 'Cat'
5 'Tomato'
6 'Sandstone'
现在,我想了解一个事实,番茄是蔬菜的一个子类,猫是动物的一个子类,等等,所有这些都在类别关系表中:
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)
这有帮助吗?完全按照“添加子类别”方法中的代码添加创建外键关系所需的内容:
//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重命名为有意义的名称,如“类别”或符合您的目的的名称
另外,我注意到没有强制的外键关系,因为您说过要添加null值。你展示你想要完成的东西的方式,我从中去掉了类别和子类别,但没有更多的层次。如果有更多级别,那么@mycargus为数据结构提供了一个很好的替代方案。如果只有这两个级别,看起来子类别需要有一个主“类别”
我建议在数据库端强制执行外键关系以防止空值,并且“category_table”中不存在的ID编写一个存储过程
第一步。根据从下拉列表中选择的类别选择“类别id”
第二步。然后使用步骤1中获得的类别id将insert写入子类别表
并从addsubcat\u Click方法调用存储过程 关于如何设计表之间的关系,您是指“如何”吗?或者,您将如何在SQL Server上创建这种关系?或者如何将关系拉到前端?@xboxremote我在将Category\u表中的类别id分配到subcategory\u表的Category列时遇到了问题。我尝试使用外键,但问题是类别表
中的id从未分配到子类别表
的类别列。在这种情况下,我们必须查看您如何插入数据。您可以发布该代码吗?我已经发布了如何添加类别和子类别的代码。@xboxremote还有,以下是我如何分配外键(我使用的是MS SQL Server Management Studio):主键表:category\u表,categoryid
外键表:subcategory\u表,categoryid
。每当我添加一个新的子类别时,它都会得到一个null
值,而不是category\u table
中的categoryid。但是每个类别都有几个子类别,子类别会根据第一个组合框(category组合框)中选择的内容加载到组合框中。嗯。我想我不明白你的问题我添加了一个具有多个子类别的给定类别的示例。要查看给定类别的所有子类别,查询如下所示:从CategoryRelationship中选择categoryId,其中parentCategoryId=a_parentCategoryId order by categoryId获取以下SqlException:必须声明标量变量“@category”。这是行不通的,因为它没有将category\u table
中的id分配给subcategory\u table
中的category列。SqlException可能是由于添加的参数中的键入错误造成的。检查以确保它们匹配。我对insert语句所做的编辑是为了将category_表中的id分配给subcategory_表中的category列,我理解您的问题,这就是您试图实现的目标。这有帮助吗?我想他是说组合框中的ID不一定是该表中的PK。因此,您的方法将分配任意FK。category_表
中的ID应设置为组合框
的ValueMember
属性,以支持OP试图完成的任务。John的代码已经表明他正在检查是否存在SelectedItem
,方法是确保组合框中的Text
属性不为空,以便在类别表中的名称后面正确分配ID,从而获得SelectedValue<