【问题标题】:Delphi - How to genericize query result setDelphi - 如何泛化查询结果集
【发布时间】:2011-12-13 18:52:31
【问题描述】:

我正在同一个应用程序中处理多个数据库。我正在使用来自两家不同公司的驱动程序。两家公司都有运行良好的 tTable 和 tQuery 后代。

我需要一种对数据进行通用访问的方法,无论我使用哪个驱动程序/tQuery 组件来返回一组数据。此数据不会与组件相关联,仅与我的逻辑相关。

例如...(伪代码)让我们创建一个可以针对任一 tQuery 组件运行的函数

function ListAllTables(NameOfDatabase : String) :ReturnSet??
begin

If NameOfDataBase = 'X' then use tQuery(Vendor 1)
    else use tQuery(Vendor 2)
RunQuery;
Return Answer...
end;

当正常运行查询时,我会这样做

Query.Open;
While not Query.EOF do
   begin
   Read my rows..
   next;
end;

如果我正在调用 ListAllTables,我的返回类型是什么,以便我可以遍历行?每个 tQuery 供应商都是不同的,所以我不能使用它(我可以,如果可以,我想要吗?)我可以构建一个内存表,并将其传回,但这似乎是 ListAllRows 构建一个额外的工作内存表,然后将其传递回调用例程,以便它可以“取消构建”,即遍历行...

您有什么想法和建议? 谢谢 GS

【问题讨论】:

    标签: delphi dataset


    【解决方案1】:

    也许您可以考虑使用通用数据访问组件,例如 UniDAC 或 AnyDAC。这允许您仅使用一个组件集以一致的方式访问不同的数据库。

    您可能还对 RemObjects 中的 DataAbstract 感兴趣。一个强大的数据抽象、多层、远程解决方案,具有很多特性。不便宜,但物超所值。

    相关链接:

    【讨论】:

    • 我实际上正在使用 AnyDAC 来支持 SQL,以及 ComponentAce 的 ABS 数据库。
    • 好的,我明白了。尽管我没有提供编码解决方案,但我不确定我关于考虑专门处理使用多个数据库的概念的组件的建议是否值得有人反对。 :(
    【解决方案2】:

    一个简单的方法是让 ListAllTables 返回(或填充)一个字符串列表。

    【讨论】:

      【解决方案3】:
      1. 您可以使用 IProviderSupport 来概括查询执行。我期待,使用的查询支持 IProviderSupport。该界面允许设置命令文本、参数、执行命令等。
      2. 使用的查询的共同点是 TDataSet。因此,您需要传递 TDataSet 引用。

      例如:

      var
        oDS: TDataSet;
      ...
      if NameOfDataBase = 'X' then
        oDS := T1Query.Create(nil)
      else
        oDS := T2Query.Create(nil);
      (oDS as IProviderSupport).PSSetCommandText('select * from mytab');
      oDS.Open;
      while not oDS.Eof do begin
        //
        oDS.Next;
      end;
      

      【讨论】:

        【解决方案4】:

        几乎所有 Delphi 数据集都源自 TDataset,最有用的行为是在 TDataset 上定义的。

        因此,如果您将每个表或查询分配给 TDataset 类型的变量,您应该能够以供应商中立的方式在该数据集上执行您的逻辑。

        我还将数据集的生产隔离为一组仅创建供应商特定数据集并将其作为 TDataset 返回的工厂函数。每个工厂功能都放在自己的单元中。然后,只有那些小单位需要了解供应商特定的组件。

        【讨论】:

        • 您不能为此使用 TDataSet 类,但如果您愿意,可以使用 TClientDataSet。
        • @Misha:为什么不呢?拉里在谈论var MyDataSet: TDataSet 和MyDataSet := TSomeSpecificDescendantDataSet.Create 或只是MyDataSet := SomeSpecificDescendentDataSetReference。然后只使用 TDataSet 提供的常用功能。完全可行。
        • @Misha:实际上,具有单个基本案例的多态后代的能力,但将后代视为是访问通用基本功能的基类是开始使用面向对象编程的主要原因之一。在我看来,TDataset 是面向对象设计最成功的用途之一。
        • +1,拉里。 @Misha,你当然可以。这正是它最初设计的目的,一直追溯到 Delphi 1。
        • 是的,我考虑的不是运行结果集,而是更多的通用数据访问本身(我脑子里有太多其他事情无法正确阅读问题),例如没有一个查询访问组件有一个基本的“类查询”抽象类
        猜你喜欢
        • 1970-01-01
        • 2012-03-09
        • 2018-08-28
        • 2015-01-26
        • 1970-01-01
        • 2017-11-16
        • 1970-01-01
        • 2021-09-12
        • 1970-01-01
        相关资源
        最近更新 更多