使用带有单独 DataSetProvider 的 ClientDataSet.AppyUpdates 主从
我使用两个 ClientDataSet 来与每个 CDS 的 DataSetProvider 建立主从关系。我不使用嵌套 CDS 来处理详细信息,因为我对主从关系进行了内存中过滤。
我遇到的问题是当我需要将更改应用到底层数据库(firebird)时。对于详细信息插入,我必须首先应用主信息,对于详细信息删除,我必须首先应用详细信息(不违反数据库中的主从关系)。到目前为止,一切都很好。但是,当我的详细 CDS 混合有 INSERT 和 DELETE 时,我该怎么办?那么我就无法在主 CDS 之前或之后应用它。
在不使用嵌套 CDS 的情况下如何处理这种情况?
I use two ClientDataSets for a master-detail relationship with a DataSetProvider for each CDS. I don’t use a nested CDS for the detail, since I do an in-memory filtering for the master-detail relationship.
The problem I have is when I need to apply my changes to the underlying database (firebird). For detail INSERTs I have to apply the master first and for detail DELETEs I have to apply the detail first (without violating the master-detail relationship in the db). So far so good. But what shall I do when my detail CDS has a mixture of INSERTs and DELETEs? Then I cannot apply it before or after the master CDS.
How can I handle such situation, without using nested CDS?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
通常,您插入/更新一条主记录,然后处理详细信息(插入、更新、删除)。解决问题的一种方法是将整个操作放在事务中(在进行任何更改之前启动事务),插入/更新主记录(单个记录),执行
MasterCDS.ApplyUpdates,处理详细记录,执行
DetailCDS.ApplyUpdates
,最后提交或回滚整个事务。由于您的 CDS 处于主/详细关系,一旦Post
发布,DetailCDS
将“查看”MasterCDS
中的记录,并且您将在MasterCDS
上ApplyUpdates
后立即获取主键值。这样您就可以保持引用完整性(外键约束),并且可以在DetailCDS
上执行任何操作。此外,
TClientDataSet
和TDataSetProvider
上都有一些事件,可以让您(几乎)完全控制整个过程,因此请仔细查看所有可用事件。注意:当我根据记忆解释这一点时,我可能对一些细节有误,但这个想法很重要。尝试一下,您就会找到解决方案。
Usually, you insert/update one master record and then you work with details (insert, update, delete). One way to solve your problem is to place the entire operation in a transaction (start transaction before making any changes), insert/update master record (single record), do
MasterCDS.ApplyUpdates
, work with detail records, doDetailCDS.ApplyUpdates
and finally commit or rollback the entire transaction. Since your CDS are in a master/detail relationship,DetailCDS
will "see" records inMasterCDS
as soon as they arePost
ed and you will get primary key value as soon as youApplyUpdates
onMasterCDS
. That way you maintain referential integrity (foreign key constraints) and you can do whatever you have on theDetailCDS
.Additionally, there are events on both
TClientDataSet
andTDataSetProvider
that give you (almost) complete control over the entire process, so take a closer look at all available events.NOTE: I may be wrong about some details as I'm explaining this from my memory, but the idea is important. Experiment a bit and you'll find the solution.
我会先应用主线,然后再应用细节。
如果您删除主记录,我将通过覆盖 BeforeApplyUpdates 事件来级联删除详细信息记录。
当您删除详细信息时,您将再次需要覆盖 BeforeApplyUpdates。如果主记录丢失,则不必执行删除。
您可以使用自定义更新命令“跳过”删除详细记录。这样做的唯一原因是阻止 datasnap 生成 SQL 命令本身,然后因为受影响的行 = 0 而失败。我可能会使用类似“
Then”的方法,在 BeforeUpdateRecord 事件中调用此命令
I would apply the master and then the detail.
In the case where you delete a master record I would cascade delete the detail records by overriding the BeforeApplyUpdates event.
When you delete the detail you will again need to override the BeforeApplyUpdates. If the master record is missing do not bother to perform a delete.
You can 'skip' the deletion of detail records by using a custom update command. The only reason to do this is to stop datasnap from generating a SQL command itself and then failing because rows affected = 0. I would probably use something like
Then in the BeforeUpdateRecord event you call this command
当使用单独的数据集提供程序时,我发现每个 DSP 中的更新都在单独的事务中(至少对于 Interbase 而言)。我并不关心这一点,但您的应用程序可能要求所有数据集保持一致。
When using separate Data Set Providers, I found that the updates in each DSP were in a separate transaction (at least with Interbase). I was not concerned with this, but your application might require all datasets to be kept consistent.