我是Delphi的新手。我通过两个TDataSetProviders连接到两个TClientDataSets(分别称为cdsA和cdsB)的两个TSQLTables(比如说A和B),两个DataSources(dsA和dsB)完成了这个场景。
让A成为主人,让B成为细节。
B.MasterSource设置为dsA值,B.MasterFields值指的是cdsA中不存在的字段(但存在于查询中)。当我启动应用程序时,我首先打开cdsA,然后打开cdsB。出了点问题。链接到dsA数据源的DBGrid显示数据,链接到dsB的DBGrid不显示任何内容。 SQLMonitor日志文件显示执行B中实现的查询(简单select a, b, c from tableB
)。如果我更改查询并显示字段'X'(select a, b, c, X from tableB
),其中'X'是由B.IndexFieldNames属性引用的字段,那么这些工作正常。
为什么链接到dsB的DBGrid不会显示与cdsA当前记录相关的B记录?仅当我在查询列中指定IndexFieldNames
时才有效吗?我错过了什么? TIA。
答案 0 :(得分:2)
我将使用 AdventureWorks 数据库为 SQL Server 2008 R2 解释完整的方案。我还假设您已经放置了TSQLConnection
组件并将其参数正确设置为与数据库建立的连接。对于此示例,我还假设其名称为 Conn1 。
在表单上,放置2 TSQLTable
(名为 tableA 和 tableB ),2 TDataSetProvider
(名为 dspA 和 dspB ),2 TClientDataSet
(名为 cdsA 和 cdsB ),2 TDataSource
(名为 dsA 和 dsB )和2 TDBGrid
(名为 gridA 和 gridB )组件。
设置属性如下:
tableA.SQLConnection = Conn1
tableA.SchemaName = Sales
tableA.TableName = Customer
tableA.Active = True
dspA.DataSet = tableA
cdsA.ProviderName = dspA
cdsA.Active = True
dsA.DataSet = cdsA
gridA.DataSource = dsA
tableB.SQLConnection = Conn1
tableB.SchemaName = Sales
tableB.TableName = SalesOrderHeader
tableB.Active = True
dspB.DataSet = tableB
cdsB.ProviderName = dspB
cdsB.MasterSource = cdsA
cdsB.MasterFields = CustomerID
cdsB.Active = True
dsB.DataSet = cdsB
gridB.DataSource = dsB
在 gridA 中,您应该会看到所有客户,而在 gridB 中,您应该只看到与此相关的订单选定的客户。
这是在Delphi中建立两个TClientDataSet组件之间的主/细节关系的基本示例。但是,还有其他方法可以做到这一点。
答案 1 :(得分:0)
Cary Jensen's book "Delphi In Depth: Client DataSets"概述了我链接ClientDataSets的方式。按照正常情况设置Master和Detail数据集,并确保它们通过TDataSource链接(您将在Detail SQL中将一个参数链接到Master)。但是,CJ建议只有一个DataSetProvider连接到Master。但是主设备(以及因此DSP)将具有重新呈现详细信息表的嵌套数据集。详细信息/嵌套数据集可以显示在主表DBGrid中或其自己的DBGrid中。您的 gridB 将链接到嵌套数据集。
将gridB直接链接回TSQLQuery的问题(据我所知)是对主CDS的任何更新都没有反映在gridB中。如果你想看到更多,那么你可以从Cary的网站下载项目NestedFromMasterDetail。
如果您真的想了解更多,请购买Cary的书。我发现它在理解客户数据集方面非常宝贵。它们设置有些不同,Cary很好地解释了它们的架构。