一、DataSource的两个主要作用:

1、连接数据集和数据感知控件

2、连接两个存在数据关系的数据集(比如数据要一起联动,或者两个数据集本身就是主从关系)

这时从数据集的DataSource要设置为指向主数据集的DataSource组件


二、两个数据集设置主从方式(针对ADO控件,因为FireDAC的Dataset没有datasource属性)

假设有两个表,teacher和student表,结构及数据如下,可以看出,一个老师有多个学生,student表通过teacherid与teacher表连接(也可以把两个表看成是主从关系)。

teacher表:

ID               TeacherName

1                     alex

2                    miley

3                     joana

4                      BBQ


Student表:

ID          StudentName        TeacherID

1                 john                          1

2                stephen                     1

3                  ooo                         1

4                 ABC                           2

5                  EFG                         2

6                 kathy                      3

7                  steph                      4


1、参数方式

两个数据集需要联动时,可以在SQL语句中使用参数的方式。

(1)dataset1的语句是select * from teacher

(2)datasource1的dataset设置为dataset1

(3)dataset2的语句是select * from student where teacherid = :id (:id说明了需要接收id参数)

(4)dataset2的datasource属性设置为datasource1

这样就完成了联动设置,当dataset1的记录变化时,由于dataset2的datasource是datasource1,所以能够接收到dataset1传过来的新的id参数。因此dataset2的记录也会根据dataset1的id不同而变化。

2、设置范围方式(巢状数据)

这种方式不需要写代码,通过组件配置就可以实现。

(1)dataset1的语句是select * from teacher

(2)datasource1的dataset设置为dataset1

(3)dataset2的语句是select * from student (这里不需要接收任何参数)

(4)dataset2的datasource属性设置为datasource1

(5)点击dataset2的masterfields的省略号,在弹出设置框中设置关联关系

这样dataset1和dataset2的主从关系就已经设置好了。


三、FireDAC设置主从关系

详细英文页面:http://docwiki.embarcadero.com/RADStudio/Rio/en/Master-Detail_Relationship_(M/D)

FireDAC设置主从也有两种方式(实际上对应ADO的两种方式):

1、基于参数的方式。和ADO的参数方式差不多,可用于 TFDQuery 或者 TFDStoredProc(只能用在这两个控件上),主从是通过重新查询实现。

2、基于范围的方式。可以用于所有FireDAC的数据集控件,它是通过设置范围的方式来实现,同时需要设置从表的IndexFieldName。(这个索引表示数据按哪个列来排列)


Feature                                                                                                          Parameter-based                 Range-based

The detail query returns a limited number of records.                                     +

The detail records are fresh.                                                                                  +

Reduced traffic and DBMS workload on each master change.                                                                     +

The cached updates preserved on the master change.                                                                                 +

Works in offline mode.                                                                                                                                        +

Supports Centralized Cached Updates with propagation                                                                             +


同时,FireDAC也有两种缓存更新方式:

1、非集中式更新。主从表各自保存各自的缓存

2、集中式的更新。主从表共享同一份更新日志,可以做到更好的控制,实现级联更新,以及实现自增值等。(个人觉得,集中式的更新,共享更新日志,是ClientDataset可以对接主表,形成巢状数据库的关键,因此巢状数据在这种方式下才能形成,不管是ADO还是FireDAC)

1、参数方式:

与ADO相同,区别在第(4)步,是将从表的MasterSource指向主表(ADO中是Datasource)。同时,可以选择是否设置MasterField字段,如果设置了就按照设置,不设置就按参数同名的字段。

2、范围方式:

前面步骤与ADO的方式相同,从第(4)步开始:

(4)dataset2的MasterSource属性设置为datasource1

(5)点击dataset2的masterfields的省略号,在弹出设置框中设置关联关系。同时设置IndexFieldNames字段(重要)

注:在从表里,MasterSource、MasterField里,指的都是主表,即关联到主表的datasource、主表的联接字段。


四、ClientDataSet主要作用:

1、作为独立的、与数据库无关的、全功能的内存数据集,实现大部分数据存储和操作功能,这时它就相当于单层数据库

2、作为多层数据库的客户端,连接本层或者中间层的provider控件(如果连接的不是本层的provider,则需要用DCOMConnect去连中间层),再由provider连接DataSet

3、存储具有主从关系的巢状数据集


五、ClientDataSet设置巢状数据库

用ClientDataSet设置巢状数据库,前提是ado组件(或其它table类组件)已经构建好了主从关系(如第二步第2点所述。

(1)放置TProvider组件,Dataset属性设置成dataset1(即主从关系的主表)

(2)将clientdataset1的providername设置成provider1,将active设置为true,可以看到,clientdataseet1已经将主从关系表数据都取回来了。其中主表数据正常显示,从表数据用一个字段表示,字段名一般为从表组件名,在这个示例中是adodataset2

(3)双击clientdataset1,弹出字段编辑器,然后点add all fields,这样就自动生成了所有字段。在单层的程序中,这一步是必要的,因为没有应用服务的connection提供信息,所以如果不手工增加一下字段信息的话,第(4)步就无法选择也无法输入巢状字段名,会报无效的字段。

(4)将clientdataset2的datafield字段设置为clientdataset1的那个包含从表数据的字段,在本例中是adodataset2字段。这时巢状数据关系就已经设置好了。