Delphi中是否有某种方法可以同时缓存主 - 详细信息行并发布主数据行和详细子行

时间:2012-06-07 20:51:33

标签: delphi ado master-detail

我想在内存中发布一些子行,然后有条件地发布它们,或者不要将它们发布到底层SQL数据库,具体取决于父行是否已发布或未发布。我不需要完整的ORM,但可能就是这样:

  1. 用户点击添加医生。添加医生对话框打开。
  2. 在“添加医生”中单击“确定”之前,在“添加医生”对话框中,用户会添加一个或多个仅存留在记忆中的患者。
  3. 用户在添加医生窗口中单击确定。现在所有患者都被储存,再加上新医生。
  4. 如果用户在医生窗口点击取消,则会丢弃所有医生和患者信息。
  5. 尝试从心理上想想如何使用delphi数据感知控件和TADOQuery或其他ADO对象来完成上述操作。如果有一种非ADO特定的方法,我也对此感兴趣,我只是把ADO扔到那里因为我碰巧在我当前的应用程序中使用MS-SQL Server和ADO。

    因此,在我以前工作过很短时间的雇主中,他们有一个名为TMasterDetail的课程,专门用于将上述内容添加到ADO记录集中。它有时会起作用,有时候它会失败一些非常有趣且难以修复的方法。

    VCL或任何第三方组件是否内置了执行此技术的强大方法?如果没有,我正在谈论上面要求ORM?我认为ORM被很多人认为是“坏”,但上面是一个非常自然的UI模式,可能会出现在一百万个应用程序中。如果我使用非ADO非Delphi-db-dataset工作方式,上面几乎不会出现我可能编写的任何持久层中的问题,但是当主键使用标识值链接时主人和细节行进入画面,事情变得复杂。

    更新:在这种情况下,交易并不理想。 (提交/回滚对我来说太粗糙了。)

1 个答案:

答案 0 :(得分:3)

你问了两个不同的问题:

  1. 如何缓存更新?
  2. 如何同时提交相关表的更新。
  3. 缓存更新可以通过多种不同方式完成。哪一个最好取决于您的具体情况:

    ADO批量更新

    由于您已经声明您使用ADO访问数据,因此这是一个合理的选择。在打开数据集之前,您只需将LockType设置为 ltBatchOptimistic ,将CursorType设置为 ctKeySet ctStatic 。然后在准备好提交时调用TADOCustomDataset.UpdateBatch。

    注意:底层OLEDB提供程序必须支持批量更新才能利用此功能。 SQL Server提供程序完全支持此功能。

    我知道在持久化数据时没有其他方法可以强制执行主/详细关系,而不是在两个数据集上按顺序调用UpdateBatch。

    Parent.UpdateBatch;
    Child.UpdateBatch;
    

    客户数据集

    数据缓存是TClientDataset存在的主要原因之一,同步主/详细关系并不困难。

    要完成此操作,您可以照常在两个数据集组件上定义主/明细关系(在您的情况下为ADOQueryADOTable)。然后创建单个提供程序并将其连接到数据集。将 TClientDataset连接到提供商,您就完成了。 TClientDatset将详细数据集解释为嵌套数据集字段,可以像访问任何其他数据集一样访问并绑定到数据感知控件。

    一旦到位,您只需致电TClientDataset.ApplyUpdates,客户数据集将负责正确订购主/详细数据的更新。

    的ORM

    关于ORM,可以说很多。太多不适合StackOverflow的答案所以我会尽量简短。

    ORM最近得到了糟糕的说唱。一些专家甚至将它们标记为反模式。我个人认为这有点不公平。对象关系映射是一个难以正确解决的难题。 ORM尝试通过抽象出在关系表和对象实例之间传输数据所涉及的大量复杂性来帮助。但与软件开发中的其他一切一样,没有银子弹,ORM也不例外。

    对于没有很多业务规则的简单数据输入应用程序,ORM可能有点过分。但随着应用程序变得越来越复杂,ORM开始变得更具吸引力。

    在大多数情况下,您会想要使用第三方ORM,而不是自己动手。编写完全符合您要求的自定义ORM听起来是个好主意并且很容易通过简单的映射开始,但您很快就会开始遇到诸如父/子关系,继承,缓存和缓存失效之类的问题(相信我,我从经验中知道这一点)。第三方ORM已经遇到了这些问题,并花费了大量资源来解决这些问题。

    使用许多ORM,您可以为代码复杂性交换代码复杂性。他们中的大多数都积极致力于通过转向约定和策略来减少样板配置。如果您将所有主键命名为Id,而不是必须将每个表的Id列映射到每个类的相应Id属性,您只需告诉ORM此约定和它假设所有表和类都知道遵循约定。您只需要覆盖不适用的特定情况的约定。我不熟悉Delphi的所有ORM,因此我无法说明支持哪个以及哪个不支持。

    在任何情况下,您都希望设计自己的应用程序架构,以便尽可能推迟决定使用哪个ORM框架(或任何框架)。