CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
不看会后悔的Windows XP之经验谈 简单快捷DIY实用家庭影院
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  .NET技术 >  VB.NET

【基础】一张表里的两个字段有父子关系,做成树。请教算法!

楼主loveme855(静静)2006-08-03 14:58:55 在 .NET技术 / VB.NET 提问

例如  
  表1  
  ID,name,fatherID  
  表2  
  ID,NAME,fatherID  
   
  表2   的fatherID与表1的ID关联  
   
  作成一张树,表2是叶子结点  
  尽可能少操作库  
   
  我用的递归,被老板骂得不行!!  
  可是我实在是没啥好办法?  
  问题点数:100、回复次数:13Top

1 楼wwfy(我舞飞扬)回复于 2006-08-03 15:14:20 得分 0

我用的递归,被老板骂得不行!!  
   
  为什么挨骂?你在递归里面频繁的操作数据库了?  
   
  树如果不大的话可以一次性的读取到DataTable里面,然后用DataTable.DefaultView.RowFilter设置条件筛选叶结点记录Top

2 楼Samen168(Code to coding)回复于 2006-08-03 15:25:50 得分 0

建树不用递归一条线往下不成,那可不叫树了,晕Top

3 楼Samen168(Code to coding)回复于 2006-08-03 15:26:11 得分 0

处理好数据读取提高下性能Top

4 楼Knight94(愚翁)回复于 2006-08-03 15:33:23 得分 0

ref:  
  http://blog.csdn.net/knight94/archive/2006/05/01/704281.aspxTop

5 楼lovebingye(降龙)回复于 2006-08-03 15:37:10 得分 0

可以简单说下你的树结构么,用数据举例!光是这样,不知道你的树的复杂程度。  
  正常设计树结构的时候都是用一个表实现的,比如  
  ID   Index   RootID  
  1     1           0  
  2     2           0  
  3     1           1  
  4     2           1  
  5     1           2  
  6     2           2  
  7     1           3  
  Top

6 楼sprc_lcl(cool一生)回复于 2006-08-03 15:41:46 得分 0

string   sqlstr   =   "select   id,name,0   as   fatherid   from   tab1   union   select   1000+id,name,fatherid   from   tab2";  
  执行付给一个dataset:ds  
  调用:buildtree(ds,0,"");  
  private   void   buildtree(DataSet   ds,int   firstfather,string   firstnull)  
  {  
  System.Data.DataView   dv=new   System.Data.DataView();  
  dv.Table=ds.Tables[0];  
  dv.RowFilter   =   "fatherid="   +   firstfather.ToString();  
  foreach(System.Data.DataRowView   drv   in   dv)  
  {  
  Response.Write(firstnull+drv["name"].ToString());  
  string   firstnull_1   =   "|------";  
  BindDropDownList2(ds,drv["id"].ToString(),firstnull_1);  
  }  
  }  
   
  参考一下,依然是递归,只取一次数据库Top

7 楼loveme855(静静)回复于 2006-08-03 16:00:56 得分 0

我们用ADO  
  本来我想弄个数据结构,整个数组  
   
  老板说不要数据结构  
   
  我弄递归她说连库太频繁~~~~  
   
  我的叶子节点要存文件所以弄帐单独的表  
   
  大致意思  
   
  和lovebingye(降龙)的表一样  
   
   
   
  sprc_lcl(cool一生)    
  猛拥着中方法我们就不弄俩表了  
   
  不过谢谢~~~  
   
  还有是不是因为我是女生就可以无限制的要求啊~~~~  
   
   
   
  我现在准备用TABLE实现  
  Top

8 楼vigorlee371(一本正经)回复于 2006-08-03 16:24:10 得分 0

女程序员少见啊。我是菜鸟,我在程序里用的也是递归。关注中……Top

9 楼lzmtw(水如烟)回复于 2006-08-03 17:14:01 得分 0

刘胖子写了些数据库设计的文章,你可以参考:  
  http://blog.csdn.net/liu7537(他自己说是胖子刘)  
   
  他对树增加了一个层次字段,用来搜索  
  如  
  ID                       TypeName                       ParentID                         TypeLevel  
  1                           根类别                               0                                   000000  
  2                           类别1                                 1                                   010000  
  3                           类别1.1                             2                                   010100  
  4                           类别1.2                             2                                   010200  
  5                           类别2                                 1                                   020000  
  6                           类别2.1                             5                                   020100  
  7                           类别3                                 1                                   030000  
  8                           类别3.1                             7                                   030100  
  9                           类别3.2                             7                                   030200  
  10                         类别1.1.1                         3                                   010101  
  Top

10 楼lzmtw(水如烟)回复于 2006-08-03 17:32:32 得分 0

引入层级字段后,我做了一个自联结表的通用类(原来叫树),象是如此:  
   
          Public   MustInherit   Class   SinceLink(Of   T   As   SinceLink.Item)  
                  Private   gCollection   As   SinceLink.Nodes(Of   T)  
                  Private   gRoot   As   T  
                  Private   gCountOfLevel   As   Integer   =   3   '层数。习惯称三层,再加上根,为四  
                  Private   gLengthEveryLevel()   As   Integer   =   {2,   2,   2}   '每层位数。根为零  
                  Private   gTotalLength   As   Integer   =   0   '总长度  
                  Private   gFirstIndexEveryLevel()   As   Integer   =   {0,   1,   3,   5}   '每层的第一位位置  
   
                  Private   gCurrentIndexEveryLevel()   As   Integer   =   {0,   0,   0,   0}   '每层的当前索引。根为零  
   
                  Sub   New(ByVal   lengthEveryLevel   As   Integer())  
                          gCountOfLevel   =   lengthEveryLevel.Length  
   
                          gLengthEveryLevel   =   lengthEveryLevel  
                          ReDim   gFirstIndexEveryLevel(gCountOfLevel)  
                          ReDim   gCurrentIndexEveryLevel(gCountOfLevel)  
   
                          gFirstIndexEveryLevel(0)   =   0  
                          gFirstIndexEveryLevel(1)   =   0  
   
                          Initialize()  
                  End   Sub  
   
  Item定义:  
          Partial   Public   Class   SinceLink  
                  <Serializable()>   _  
                  Public   MustInherit   Class   Item  
                          Private   gID   As   Integer  
                          Private   gName   As   String  
                          Private   gDeclare   As   String  
                          Private   gParentID   As   Integer  
                          Private   gLevel   As   String  
   
  最后在三层四层之类的树稍为继承不用几行代码就OK了Top

11 楼lzmtw(水如烟)回复于 2006-08-03 17:38:05 得分 0

比如两层菜单的实现.如File->Exit.我在练习做一个插件类的主界面,只用两层。  
   
  定义非常简单,什么都不用加:  
  Namespace   AddIns.Menu  
          <Serializable()>   _  
          Public   Class   MenuItem  
                  Inherits   uCollection.SinceLink.Item  
          End   Class  
  End   Namespace  
   
  那个操作控制类仅只是将Item与相应菜单项关联起来,并做了初始化工作:  
  Imports   System.Windows.Forms  
  Namespace   AddIns.Menu  
          Public   Class   MenuManager  
                  Inherits   uCollection.SinceLink(Of   MenuItem)  
   
                  Private   gMainForm   As   Windows.Forms.Form  
   
                  Sub   New(ByVal   form   As   Form)  
                          MyBase.New(New   Integer()   {2,   2,   2})  
                          gMainForm   =   form  
                          If   Me.Collection.LastIndex   =   1   Then   Initialize()  
                  End   Sub  
                  Private   Sub   Initialize()  
                          AddMenu(Root,   MenuEnum.File)  
                          AddMenu(Root,   MenuEnum.Edit)  
                          AddMenu(Root,   MenuEnum.View)  
                          AddMenu(Root,   MenuEnum.Format)  
                          AddMenu(Root,   MenuEnum.Tools)  
                          AddMenu(Root,   MenuEnum.Window)  
                          AddMenu(Root,   MenuEnum.Community)  
                          AddMenu(Root,   MenuEnum.Help)  
                          AddMenu(Me.Collection.Items(MenuEnum.File.ToString,   uCollection.SinceLink.Searchway.Name)(0),   MenuEnum.Exit)  
                          AddMenu(Me.Collection.Items(MenuEnum.File.ToString,   uCollection.SinceLink.Searchway.Name)(0),   MenuEnum.AddIns)  
                          Me.Save()  
                  End   Sub  
   
                  Private   Sub   AddMenu(ByVal   parent   As   MenuItem,   ByVal   menu   As   MenuEnum)  
                          Add(parent,   menu.ToString).Declare   =   SR.GetString(String.Format("MenuItem_{0}",   menu.ToString))  
                  End   Sub  
   
   
                  Public   Function   AddMenuItem(ByVal   item   As   MenuItem,   ByVal   action   As   EventHandler)   As   ToolStripMenuItem  
                          Dim   mToolStripMenuItem   As   ToolStripMenuItem   =   Nothing  
   
                          If   item.ParentID   =   Root.ID   Then  
                                  mToolStripMenuItem   =   AddMenu(Nothing,   item.Name,   item.Declare,   action)  
                          Else  
                                  mToolStripMenuItem   =   AddMenu(GetMenuItem(Parent(item).Name),   item.Name,   item.Declare,   action)  
                          End   If  
   
                          Return   mToolStripMenuItem  
                  End   Function  
   
                  Public   Function   GetMenuItem(ByVal   name   As   String)   As   ToolStripMenuItem  
                          Dim   mToolStripMenuItem   As   ToolStripMenuItem   =   Nothing  
                          Dim   mSearchResult   As   ToolStripItem()  
                          Dim   mKey   As   String   =   String.Format("{0}ToolStripMenuItem",   name)  
   
                          mSearchResult   =   gMainForm.MainMenuStrip.Items.Find(mKey,   True)  
                          If   mSearchResult.Length   =   1   Then  
                                  mToolStripMenuItem   =   CType(mSearchResult(0),   ToolStripMenuItem)  
                          End   If  
   
                          Return   mToolStripMenuItem  
                  End   Function  
   
                  Public   Sub   AddSeparatorItem(ByVal   parent   As   ToolStripMenuItem)  
                          parent.DropDownItems.Add(New   ToolStripSeparator)  
                  End   Sub  
   
                  Private   Function   AddMenu(ByVal   parent   As   ToolStripMenuItem,   ByVal   name   As   String,   ByVal   text   As   String,   ByVal   action   As   EventHandler)   As   ToolStripMenuItem  
                          Dim   mMenuStrip   As   MenuStrip   =   gMainForm.MainMenuStrip  
                          If   mMenuStrip   Is   Nothing   Then  
                                  mMenuStrip   =   New   MenuStrip  
                                  gMainForm.Controls.Add(mMenuStrip)  
                                  gMainForm.MainMenuStrip   =   mMenuStrip  
                          End   If  
   
                          Dim   mToolStripMenuItem   As   ToolStripMenuItem   =   GetMenuItem(name)  
   
                          If   mToolStripMenuItem   Is   Nothing   Then  
                                  mToolStripMenuItem   =   New   ToolStripMenuItem(text)  
                                  Dim   mKey   As   String   =   String.Format("{0}ToolStripMenuItem",   name)  
                                  mToolStripMenuItem.Name   =   mKey  
                                  AddHandler   mToolStripMenuItem.Click,   action  
   
                                  If   parent   Is   Nothing   Then  
                                          mMenuStrip.Items.Add(mToolStripMenuItem)  
                                  Else  
                                          parent.DropDownItems.Add(mToolStripMenuItem)  
                                  End   If  
                          End   If  
   
                          Return   mToolStripMenuItem  
                  End   Function  
   
          End   Class  
  End   Namespace  
  Top

12 楼lzmtw(水如烟)回复于 2006-08-03 17:41:01 得分 0

哦,那个可以实现三层菜单的,定义是如此    
  MyBase.New(New   Integer()   {2,   2,   2})Top

13 楼lzmtw(水如烟)回复于 2006-08-03 17:49:32 得分 0

这是一个插件。加载后主窗体加了一个菜单项   测试->Form  
  留意的是点击Form弹出一个窗体,这个窗体加上了基本的菜单项  
  并且File下头的Exit菜单与主窗体的某方法关联上了,换句话说,实现了插件与主窗体程序的交互,数据交流。  
   
  还是试试阶段,娱乐娱乐。  
   
  <Base.AddIns("TestForm",   "AboutIns.TestForm",   Author:="LzmTW",   Description:="测试窗体",   Version:="1.0.0.0",   Lasttime:="2007年7月29日")>   _  
  Public   Class   TestForm  
   
          Implements   LzmTW.AddIns.Base.IPackage  
          Shared   Sub   Main()  
   
          End   Sub  
   
          Dim   f   As   Windows.Forms.Form  
          Private   Test   As   Windows.Forms.ToolStripMenuItem  
          Private   WithEvents   TestForm   As   Windows.Forms.ToolStripMenuItem  
          Public   Sub   Load(ByVal   appContext   As   Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase)   Implements   LzmTW.AddIns.Base.IPackage.Load  
                  f   =   appContext.ApplicationContext.MainForm  
                  Test   =   New   Windows.Forms.ToolStripMenuItem("测试(&T)")  
                  TestForm   =   New   Windows.Forms.ToolStripMenuItem("Form(&F)")  
                  Test.DropDownItems.Add(TestForm)  
                  f.MainMenuStrip.Items.Add(Test)  
                  Console.WriteLine(System.Reflection.Assembly.GetEntryAssembly.EntryPoint.DeclaringType.FullName)  
          End   Sub  
   
          Public   Sub   Unload()   Implements   LzmTW.AddIns.Base.IPackage.Unload  
                  f.MainMenuStrip.Items.Remove(Test)  
          End   Sub  
   
          Private   Sub   TestForm_Click(ByVal   sender   As   Object,   ByVal   e   As   System.EventArgs)   Handles   TestForm.Click  
                  Dim   f1   As   New   Windows.Forms.Form  
                  f1.Text   =   "this   is   a   test   from"  
                  Dim   t   As   New   LzmTW.AddIns.Menu.MenuManager(f1)  
                  For   Each   item   As   LzmTW.AddIns.Menu.MenuItem   In   t.Children(t.Root,   False)  
                          t.AddMenuItem(item,   Nothing)  
                  Next  
   
                  Dim   h   As   EventHandler   =   CType(eventhandler.CreateDelegate(GetType(EventHandler),   f,   "TestToolStripMenuItem_Click"),   EventHandler)  
                  For   Each   item   As   LzmTW.AddIns.Menu.MenuItem   In   t.Children(t.Collection.Items(Menu.MenuEnum.File.ToString,   LzmTW.uCollection.SinceLink.Searchway.Name)(0),   False)  
                          t.AddMenuItem(item,   h)  
                  Next  
                  f1.Show()  
          End   Sub  
   
          Private   Sub   Hello(ByVal   sender   As   Object,   ByVal   e   As   System.EventArgs)  
                  MsgBox("Hello       "   &   sender.ToString)  
          End   Sub  
  End   Class  
  Top

相关问题

关键词

得分解答快速导航

  • 帖主:loveme855

相关链接

  • CSDN .NET频道
  • .NET类图书
  • C#类图书
  • .NET类源码下载

广告也精彩

反馈

请通过下述方式给我们反馈
反馈
提问
网站简介|广告服务|VIP资费标准|银行汇款帐号|网站地图|帮助|联系方式|诚聘英才|English|问题报告
北京创新乐知广告有限公司 版权所有, 京 ICP 证 070598 号
世纪乐知(北京)网络技术有限公司 提供技术支持
Copyright © 2000-2008, CSDN.NET, All Rights Reserved
GongshangLogo