我实际测试的结果是Filter要慢很多,在我试过的几种方案中现在用的已经是最快的了,我把关键代码贴出来大家看看。 procedure TForm1.AddSubTree(Node: TTreeNode; ID: Integer); var s:string; ParentNode:TTreeNode; MyDataSet:TClientDataSet; begin MyDataSet:=TClientDataSet.Create(nil); MyDataSet.RemoteServer:=SocketConnection1; MyDataSet.ProviderName:='projects_DataSetProvider1'; s:='SELECT ID,NAME,PARENT_ID,KIND FROM COMPONENTS WHERE ID='+IntToStr(ID); MyDataSet.Close; MyDataSet.CommandText:=S; MyDataSet.Open; if MyDataSet.FieldByName('KIND').AsString<>'dir' then begin MyDataSet.Free; Exit; end; ParentNode:=treeviewBase.Items.AddChild(node,MyDataSet.FieldByName('NAME').AsString);//+'(A)'); s:='SELECT ID FROM COMPONENTS WHERE PARENT_ID='+IntToStr(ID); MyDataSet.Close; MyDataSet.CommandText:=S; MyDataSet.Open; while not MyDataSet.EOF do begin AddSubTree(ParentNode,MyDataSet.FieldByName('ID').AsInteger); MyDataSet.Next; end; MyDataSet.Free; end;
我觉得这样一来还是每作一次查询就要从服务器上取一次数据,可以一次性取得数据,然后对MyDataSet本地数据集进行操作,不用频繁的对其Open or Close
Sorry,I can not input Chinese.I had said it that using filter is more low efficiency than my current solution by my experiment.I just think like you to treat ClientDataSet to a off-line DataBase,but how can I query from it?That is the point.Thank you!
┏━★━━◆━━★━┓
♂欢|◢CSDN◣|使♂ ▲自由保存帖子,浏览,关注检测
┃迎|◥论坛助手◤|用┃ ▲完善的CSDN客户端工具
┗━☆━━◇━━━☆┛ ▲自动添加签名......让你更快,更爽,更方便地上CSDN...
http://www.csdn.net/expert/topic/573/573604.xml
http://www.chinaok.net/csdn/csdn.zip
┏━★━━◆━━★━┓
♂欢|◢CSDN◣|使♂ ▲自由保存帖子,浏览,关注检测
┃迎|◥论坛助手◤|用┃ ▲完善的CSDN客户端工具
┗━☆━━◇━━━☆┛ ▲自动添加签名......让你更快,更爽,更方便地上CSDN...
http://www.csdn.net/expert/topic/573/573604.xml
http://www.chinaok.net/csdn/csdn.zip
用clientdataset的filter吧,对数据进行过滤。
procedure TForm1.AddSubTree(Node: TTreeNode; ID: Integer);
var
s:string;
ParentNode:TTreeNode;
MyDataSet:TClientDataSet;
begin
MyDataSet:=TClientDataSet.Create(nil);
MyDataSet.RemoteServer:=SocketConnection1;
MyDataSet.ProviderName:='projects_DataSetProvider1';
s:='SELECT ID,NAME,PARENT_ID,KIND FROM COMPONENTS WHERE ID='+IntToStr(ID);
MyDataSet.Close;
MyDataSet.CommandText:=S;
MyDataSet.Open;
if MyDataSet.FieldByName('KIND').AsString<>'dir' then
begin
MyDataSet.Free;
Exit;
end;
ParentNode:=treeviewBase.Items.AddChild(node,MyDataSet.FieldByName('NAME').AsString);//+'(A)');
s:='SELECT ID FROM COMPONENTS WHERE PARENT_ID='+IntToStr(ID);
MyDataSet.Close;
MyDataSet.CommandText:=S;
MyDataSet.Open;
while not MyDataSet.EOF do
begin
AddSubTree(ParentNode,MyDataSet.FieldByName('ID').AsInteger);
MyDataSet.Next;
end;
MyDataSet.Free;
end;
1、将所有的数据取到本地;
2、采用深度优先的方式对数据进行排序(生成平铺的树形结构)
3、一次性将所有节点加入到TreeView中
尽量不要采用递归的方式,虽然好理解,但是效率太低。采用我上面的方法,9000多个节点,共有3层的数据,从打开数据库连接到最终在本地TreeView当中显示,不会超过10秒钟
例如:TreeView1.Items.BeginUpdate;{添加树的语句}TreeView1.Items.EndUpdate;
可提高一定的速度
数据库:Paradox
编译环境:Delphi6 + WindowsXp
运行环境:Athlon 1600+ 256M Ram WindowsXp
数据压力:6 * 6 * 6 * 6 * 6共9770条数据
运行时间(包括读取数据,排序,加入TreeView控件):1秒;略加修改可以在三层结构中运行;
在DBServer端,用存储过程一次将需要要用(可以是全部,也可以是部分,根据你的策略而定)的数据产生一个符合树结构的临时数据表,把表数据取回客户端,在客户端我用的是dxdbtreeview控件,将数据源连接上就可显示树,无须再自己一个一个节点写了而且还能扩展,
我大约20万的树记录如果全部一次生成也不超过一分钟,如果分步实现根本没延迟的感觉to kongse(空色):
至于离线的TclientDataSet,你可以用一个TclientDataSet专作查询, 将结果Data赋给另一个
单独(不要RemoteServer,ProviderName等)的TclientDataSet 做Filter,locate等操作
它不就是相当一个离线DB...
1)取回建树必需的所有数据;
2)断开与服务器的连接;
3)全部生成:建立CDS的索引(要求表中有“层”的字段),向下滚记录,添加结点;
4)动态生成:建立CDS的索引(要求表中有“层”的字段),LOCATE(层信息)后下滚。
有人支持吗?