Delphi 的 DataSetProvider.Options 里面的 poCascadeUpdates 修改嵌套表的主键

缘起

用 Delphi 的多层数据库开发框架,实现一个多层的主从表,从服务器端到客户端,可以采用这样的架构会让代码比较简单:

1. 假设数据库里面有 2 个表,构成主从表的架构;比如,一个是学生名单表,以身份证号码为主键,这个表是主表;有一个学生各科成绩表,每个学生每科(语文,数学,外语)一条记录,作为从表。

2. Delphi 的服务器端,使用 2 个 FdQuery 对应上述两个表。其中,FdQuery1 对应学生明单表,是主表。FdQuery2 对应成绩表,是从表。一个 DataSource1 指向 FdQuery1,然后 FdQuery2 的 MasterSource 指向 DataSource1,MasterField 设置为主键(身份证号码字段);然后,放置一个 DataSetProvider1 它的 DataSet 设置为 FdQuery1;

3. Delphi 的客户端:ClientDataSet1 的 ProviderName 设置为服务器端的 DataSetProvider1;给 ClientDataSet1 在设计期增加字段,Delphi IDE 自动从服务器端获得字段数据,自动填充字段。这些字段里面,有一个字段是代表了服务器端的 FdQuery2;然后设置 ClientDataSet2 的 DataSetField 为前述字段(IDE 里面的属性面板里面找到 DataSetField 属性,下拉,就能选择)。

经过上述散布,一个简单的 3 层架构的嵌套表的编辑界面就有了。

好处:

这样的嵌套表界面的好处是,在客户端修改了主表和从表的数据,只需要提交 ClientDataSet1,而且,在服务器端的 DataSetProvider1.BeforeUpdateRecord 事件里面,可以看到主表修改的数据,也可以看到从表修改的数据,在这里,可以写入业务逻辑代码,比如某个字段不允许修改。

问题

上述架构下,新增主表和从表的数据,然后提交,没问题。同时修改了主表和从表的数据然后提交,也没问题。但是,如果要修改主表的主键字段的值,Delphi 直接弹出异常提示:没用 Cascade XXX

问题的解决

解决以上问题,需要做以下几步:

1. 首先,在数据库里面(我这里使用的是 FireBied 数据库),给从表设置一个指向主表主键的外键,并且这个外键需要设置为 Cascade Updates;这个必须是数据库本身支持的才行;

2. DataSetProvider1 的 Options 里面,设置 poCascadeUpdates 属性为 True (属性面板里面选择打勾);

完成上述两步,再次运行程序,你会看到,如果在客户端修改了主表的主键字段的值,从表的主键字段的值自动跟随变化。修改后如果执行 ClientDataSet1.ApplyUpdates(0) 提交客户端的数据,在数据库里面,主表和从表的主键字段的值都被更新了。

探索

如果在 DataSetProvider1.BeforeUpdateRecord 里面写代码跟踪,假设上述操作仅仅修改了主表的主键的值,这个事件里面它只触发了一次主表的提交,没用从表的提交动作。因此,真正的同时修改主表和从表在数据库里面的值,是数据库自己实现的。

如果数据库里面没用为从表创建外键,只是 DataSetProvider1.Options 里面为 poCascadeUpdates 属性打勾,可以从 DataSetProvider1.BeforeUpdateRecord 事件里面看到仅仅触发了一次主表的提交动作,再看数据库,仅仅是主表的主键值更新了,从表没有。

当然,如果从表里面修改了其它字段,在 DataSetProvider1.BeforeUpdateRecord 里面仍然能够触发相应的事件的。

另外:

假设我们有 4 个表:T1, T2, T3, T4;

T1 是主表,T2,T3 是 T1 的从表;T4 是 T3 的从表。构成了 2 级主从嵌套;

仍然采用上述服务器端嵌套表的架构。T2, T3, T4 都有外键指向主表的主键。

此时,在客户端,修改了主表的主键,会看到 T2, T3 的主键自动跟随改变,但 T4 的主键没用变化。但是,如果此时提交,在数据库里面,T1, T2, T3, T4 的主键都同时被更新了。在 Delphi 这边,仅仅需要刷新一下显示就可以了。客户端刷新显示,最简单的代码就是:ClientDataSet1.Refresh;

总结

1. 普通用法:假设主表和从表的非主键字段的值在客户端同时被修改,提交后,会在服务器端的 DataSetProvider1.BeforeUpdateRecord 触发事件。可以在事件里面判断当前触发的是主表还是从表。因为程序员知道每个表的字段名称,因此可以针对当前触发事件的表的记录的每个字段,进行权限控制,或者值的修改,等等。也就是业务逻辑控制在服务器端,安全性更高。

2. 修改主键:嵌套表如果修改主键,采用设置 DataSetProvider1.Options 里面的 poCascadeUpdates 属性的方式,客户端修改主表主键值,从表自动跟随变化;客户端提交,在 DataSetProvider1.BeforUpdateRecord 事件里面,只有主表提交,没用从表提交的事件。这种情况从表的更新,依靠的是数据库本身的主从表设置 -- 也就是数据库里面为从表创建指向主表主键的外键。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值