在 C# 中将树存储和检索到 SQL 中






3.26/5 (12投票s)
在本文中,将介绍 Microsoft SQL Server 数据库在存储和检索树方面的能力。

引言
在本文中,将介绍 Microsoft SQL Server 数据库在存储和检索树方面的能力。在示例应用程序中,PropertyGrid
组件已被用于更改树,例如“添加/删除/编辑/向上移动/向下移动根和子节点”。

先决条件
您必须首先安装 Microsoft SQL Server Express Edition 2005 并创建一个名为“cm_express
”的实例,然后运行此程序。 Microsoft SQL Server Express Edition 2005 是免费软件,并且已经存在于下面的链接中供下载
http://go.microsoft.com/fwlink/?LinkId=65212
背景
在此示例中,我们使用 Microsoft SQL Server 2005 Express Edition 在 .NET 应用程序下构建树。 该树有 3 个级别,每个级别都有无数个根节点,每个根节点都有无数个子节点,而每个子节点又有很多子节点。
请注意,如果您有三个级别,那么您应该在数据库中创建两个表,或者通常如果您有 n 个级别,那么您应该在数据库中创建 n-1 个表。 每个表有两个字段,第一个字段显示父节点,第二个字段显示每个级别的子节点。
Notice
您可能在不同级别有两个具有相同名称的节点,例如,级别 2 中的第二个节点的名称与级别 3 中的第一个节点的名称相同,因此我们应该在数据库中提及每个命名节点的路径。
使用演示应用程序
安装 Microsoft SQL Server 2005 Express Edition 后,您可以运行该应用程序。 要更改树,您应该单击 Nodes 属性中 (Collection) 旁边的按钮,然后将出现 TreeNode Editor。 在此窗体中,您可以添加/删除/编辑/向上移动/向下移动根和子节点。 要编辑节点文本,您必须更改 Text
属性。 之后,您应该单击“确定”按钮以保存并退出当前窗体,并且您还必须在主窗体中单击“应用更改”按钮以设置数据库信息。
源代码说明
加载主窗体后,首先我们检查 SQL 连接。 如果连接失败,将出现一条消息,通知您“安装 Microsoft SQL Server Express Edition 2005”作为前提条件,然后尝试附加树数据库。 如果数据库已经存在,则不会运行任何操作。 为了附加树数据库,我使用了以下代码
// Attach tree database
SqlCommand sqlcm = new SqlCommand();
Sqlcon.Open();
sqlcm.Connection = Sqlcon;
try
{
sqlcm.CommandText = "EXEC sp_attach_db @dbname = N'tree', @filename1 = N'"
+ Application.StartupPath + "\\tree.mdf" + " ', @filename2 = N'"
+ Application.StartupPath + "\\tree_log.ldf" + " ' ";
sqlcm.ExecuteNonQuery();
Sqlcon.Close();
}
catch { }
要创建树,首先我们从 t1
读取根节点,并将它们插入到 TreeView
中; 然后我们从 t2
读取这些根节点的子节点,并将这些子节点插入到 TreeView
中。
// Load tree from database
SqlConnection sqlconn = new SqlConnection(cs2);
SqlConnection sqlconn2 = new SqlConnection(cs2);
sqlconn.Open();
sqlconn2.Open();
SqlCommand sqlcmd = new SqlCommand("select * from t1", sqlconn);
SqlDataReader data = sqlcmd.ExecuteReader();
SqlCommand sqlcmd2 = new SqlCommand();
sqlcmd2.Connection = sqlconn2;
SqlDataReader data2;
string lvl1, lvl2, lvl3, lv2, lv3;
int myindex, myindex1, i, j, k;
myindex1 = myindex = i = j = k = 0;
while (data.Read())
{
lvl1 = data["lvl1"].ToString();
treeView1.Nodes.Insert(i, lvl1);
lvl2 = data["lvl2"].ToString();
j = 0;
while (lvl2 != "")
{
myindex = lvl2.IndexOf('|');
lv2 = lvl2.Substring(0, myindex);
treeView1.Nodes[i].Nodes.Insert(j, lv2);
sqlcmd2.CommandText = "select * from t2 where lvl2='" + lvl1+ '|'+ lv2+ "'";
data2 = sqlcmd2.ExecuteReader();
while (data2.Read())
{
lvl3 = data2["lvl3"].ToString();
k = 0;
while (lvl3 != "")
{
myindex1 = lvl3.IndexOf('|');
lv3 = lvl3.Substring(0, myindex1);
treeView1.Nodes[i].Nodes[j].Nodes.Insert(k, lv3);
if (lvl3.Length <= (myindex1 + 1))
lvl3 = "";
else
lvl3 = lvl3.Substring(myindex1 + 1, lvl3.Length - (myindex1 + 1));
k++;
}
}
data2.Close();
if (lvl2.Length <= (myindex + 1))
lvl2 = "";
else
lvl2 = lvl2.Substring(myindex + 1, lvl2.Length - (myindex + 1));
j++;
}
i++;
}
data.Close();
sqlconn.Close();
sqllconn2.Close();
当用户单击“应用更改”按钮时,第一次将删除 t1
和 t2
中的所有项目,然后将父节点和子节点插入到表中。
SqlConnection sqlconn = new SqlConnection(cs2);
sqlconn.Open();
SqlCommand sqlcmd = new SqlCommand("Delete from t1", sqlconn);
sqlcmd.ExecuteNonQuery();
sqlcmd.CommandText = "Delete from t2";
sqlcmd.ExecuteNonQuery();
int i1, i2, i3;
i1 = 0;
while (i1 < treeView1.Nodes.Count)
{
sqlcmd.CommandText = "insert into t1(lvl1)
values('" + treeView1.Nodes[i1].Text + "')";
sqlcmd.ExecuteNonQuery();
i2 = 0;
while (i2 < treeView1.Nodes[i1].Nodes.Count)
{
sqlcmd.CommandText = "insert into t2(lvl2) values('"
+ treeView1.Nodes[i1].Text + '|' + treeView1.Nodes[i1].Nodes[i2].Text + "')";
sqlcmd.ExecuteNonQuery();
sqlcmd.CommandText = "update t1 set lvl2 = IsNull(lvl2,'') + '"
+ treeView1.Nodes[i1].Nodes[i2].Text + "'+'|' where lvl1 ='"
+ treeView1.Nodes[i1].Text + "' ";
sqlcmd.ExecuteNonQuery();
i3 = 0;
while (i3 < treeView1.Nodes[i1].Nodes[i2].Nodes.Count)
{
sqlcmd.CommandText = "update t2 set lvl3 = IsNull(lvl3,'') + '"
+ treeView1.Nodes[i1].Nodes[i2].Nodes[i3].Text + "'+'|' where lvl2 ='"
+ treeView1.Nodes[i1].Text + '|' + treeView1.Nodes[i1].Nodes[i2].Text + "' ";
sqlcmd.ExecuteNonQuery();
i3++;
}
i2++;
}
i1++;
}
sqlconn.Close();
历史
- 2007 年 6 月 17 日:初始发布