我找到了一些教程,但他们仍然给我留下了问题。
我们来看一个2个表的经典例子,一个用于客户详细信息,另一个用于订单详细信息。
数据库中的customers
表具有:
customer_id
作为主键 orders
表格包含:
customer_id
,它是引用customers
表order_value
我需要两个数据集组件,两个查询和一个连接。
到目前为止,这么好吗?或者我已经错过了什么?
现在,教程说我必须设置数据源的MasterSource,它对应于DB网格,显示orders
表是与customers
表对应的数据源和MasterFields
,在本例中为customer_id
。
还有别的吗?例如,我应该将与Detailfields
表对应的数据源查询的customers
设置为customer_id
吗?
我应该使用这些属性,还是a paramaterized query?
好的,此时,我们已经按照经典教程进行操作,可以滚动customers
数据库网格,查看orders
数据库网格中显示的当前客户的所有订单。当用户单击customers
数据库网格时,我必须关闭();然后打开(); orders
查询以刷新其对应的数据库网格。
然而,这些教程似乎总是假定一个静态数据库,其中包含永远不会改变的现有内容。
当我问一个问题时,我给出了一个例子,我使用了一个命令来INSERT INTO orders...
并被告知那是一件坏事,我应该:
这是对的吗?
我问,因为在我看来,命令将数据放入,查询应该只将输出,但我可以看到命令没有通过数据源的查询链接到数据库网格。
这是一个选择问题,还是必须使用查询?
如果是这样,似乎我甚至不能使用简单的SQL函数,例如SUM,MIN<查询中的AVG,MAX必须将它们移动到我的代码中。
如果我必须使用该查询,我该如何实现SQL UPDATE
和DROP
?
最后,我可以拥有Master / Detail / Detail关系吗?
假设我想要一个第三个数据库网格,它显示了客户所有订单的总数和平均值。它从orders
表中获取数据(但不能使用SUM和AVG),每次用户选择不同的客户时都会更新,从而提供主/明细/详细关系。我只是将其设置为两个主/细节关系? I.E,DB网格,数据源,总订单和平均订单的查询仅指orders
,并且没有customers
的引用,即使它确实使用customer_id
?
提前感谢您的任何帮助和澄清。我希望这个问题将来会成为其他人的参考(所以,随时编辑它)。
答案 0 :(得分:1)
TLDR:在SQL世界中,Master / Detail是一种古老的。
当有人说“Master Detail”时,他们不会一直走到兔子洞口。你的问题表明你确实想要。我想分享一些我认为有用的东西,但我不认为任何人都可以完全回答你的问题。
对于任何两个数据集,出于某些人的目的,主细节的最小实现只不过是当主表中当前选定的行发生更改时触发的事件处理程序。然后,此行用于过滤详细信息表数据集中的行,以便只显示与主行的主键匹配的行。如果你在Delphi的VCL中的大多数类似TTable的对象中正确配置它,那么这是为你完成的,但是如果你愿意写的话,即使没有明确支持主/详细配置的数据集也能以这种方式运行。一些事件处理程序和过滤数据。
在我以前的一个雇主中,一个人发明了一个Master Detail控制器组件,它与一个名为Kamiak的Delphi的ADO组件的一个鲜为人知的变体,它有一些属性,只有那些人熟悉BDE-TTable时代的主要细节概念是不可预料的。这是一项非常聪明的工作,它具有以下特点:
像上面的滚动你自己的ORM方法一样可爱,并不是没有它的黑暗面。系统中的奇怪错误使我永远不想再次使用这种方法。我不想夸大事情,但是我可以谦卑地暗示,在主人细节兔洞中走得太远了吗?不要去那里。或者,如果你这样做,意识到你真的在构建一个迷你ORM,并准备好做这项工作,其中应包括一套非常可靠的单元测试和集成测试。即便如此,请注意你可能会发现一些非常奇怪的角落案例,并且可能会发现一些真正邪恶的错误潜伏在你美丽的ORM / MasterDetail中。
就插入而言,当然取决于您是构建者还是用户。如果你不害怕SQL,那么满足于在VCL中构建任何Table类并且永远不想用SQL弄脏他们的人的人会认为你的方法是错误的。我不知道那个人将如何处理自动分配的身份主键。我将一个人记录存储在一个表中,我立即需要获取该人新分配的ID,这是一个整数,我现在将使用该整数主键,将我的详细行与主行关联,详细信息行,因此引用主行的ID整数,作为外键,因为我的SQL数据库构造良好,具有参照完整性约束,并且因为我事先考虑了所有这些并且不想这样做一遍又一遍,我最终从这里开始,构建一个对象关系映射框架。我希望你能看到你的许多问题如何有许多可能的答案,答案导致数百或数百万种可能的方法,而且没有一个正确的答案。我碰巧是ORM中的一个不相信者,而且我觉得在这个疯狂的火车上下车的安全之地就在你上车之前。我手工编写我的SQL代码,然后手工编写我的业务对象代码,而且我不使用任何花哨的Master Detail或ORM东西。但是,您可以选择按自己喜欢的方式进行操作。
我将在BDE / dBase /平面文件时代实现“主要细节”,我现在只是作为主行的查询实现,第二次查询细节行,当主行更改时,我刷新了详细信息行查询,并且我根本不使用TTable对象中的MasterSource
或相关的Master / Detail属性。