Page 1 of 1
Uniquery + DataSetProvider + ClientDataSet Master Detail
Posted: Wed 09 Jan 2013 22:32
by rrcanalista
Hi, I have the follow components
UniQuery1 -> DataSetProvider1 -> ClientDataSet1 (Master) -> DataSource1
UniQuery2 -> DataSetProvider2 -> ClientDataSet2 (Detail) -> DataSource2
ClientDataSet2.MasterSource = DataSource1
ClientDataSet2.MasterField = 'MasterID'
ClientDataSet2.IndexFieldNames = 'DetailMasterID'
When I open the both, they work but if navigate in the CDS1 shows the exception "Key Violation"
I have set Providerflags correctly of the CDS and Uniquery and shows the same error.
So, what's the best way to make master/detail in this scenario?
Re: Uniquery + DataSetProvider + ClientDataSet Master Detail
Posted: Thu 10 Jan 2013 12:16
by AlexP
Hello,
Please specify your versions of UniDAC, IDE, and the name of the DB your are working with. In addition, send a project demonstrating the problem to alexp*devart*com (including scripts for creating and filling tables).
Re: Uniquery + DataSetProvider + ClientDataSet Master Detail
Posted: Fri 11 Jan 2013 00:37
by rrcanalista
Hi, I realize that the error shows when the detail is empty.
unidac 4.6.11 Delphi XE2 using Firebird 2.5.
I sent a project sample with the database DEMO.fdb
Re: Uniquery + DataSetProvider + ClientDataSet Master Detail
Posted: Fri 11 Jan 2013 13:00
by AndreyZ
Thank you for the information. We have reproduced the problem and investigation of the problem is in progress. As soon as we have any results, we will let you know.
As a workaround, you can set the PacketRecords option of the detail TClientDataSet component to -1.
Re: Uniquery + DataSetProvider + ClientDataSet Master Detail
Posted: Fri 11 Jan 2013 14:04
by rrcanalista
Thank you for the information. It works, another question, is there any performance problem if I use CDS2.PacletRecord=-1 instead 0? is this the really right way to make master/detail with clientdataset?
Re: Uniquery + DataSetProvider + ClientDataSet Master Detail
Posted: Mon 14 Jan 2013 13:35
by AndreyZ
No, there is no performance problems when using PacketRecord = -1 for the detail TClientDataSet. dbExpress technology uses PacketRecord = -1 for the detail TClientDataSet internally when fetches data for it.
Yes, it is a correct way of establishing of master/detail relationships using TClientDataSet components.
Re: Uniquery + DataSetProvider + ClientDataSet Master Detail
Posted: Tue 15 Jan 2013 20:13
by Johan.Swart
Hi,
Could you perhaps post your example of using ClientDataSet with the UniDAC components in a master detail setup.
I would very like to learn from your example.
Alternatively, please email me
[email protected]
Regards,
Johan Swart
Re: Uniquery + DataSetProvider + ClientDataSet Master Detail
Posted: Tue 15 Jan 2013 21:08
by rrcanalista
Hi, no problem, I have send to you the Demo.
Re: Uniquery + DataSetProvider + ClientDataSet Master Detail
Posted: Wed 06 Feb 2013 10:30
by AndreyZ
We thoroughly investigated this question. The 'Key Violation' error occurs because of a bug in the TCustomClientDataSet.CheckDetailRecords method (it is declared in the DBClient unit). When PacketRecords is set to 0, TClientDataSet must load only metadata, but instead it loads all data of the detail table from the server to its buffer. The following code demonstrates this:
Code: Select all
AddDataPacket(DoGetRecords(-1, RecCount, 0, '', MasterValues), False); // as you can see, -1 (all records) is used instead of 0 (metadata only)
When the detail table is empty, TClientDataSet initiates another request to the server. Again, all data of the detail table are fetched from the server and TClientDataSet tries to put it to its buffer. Because all records are already in the buffer, it violates the primary key constraint. This causes the 'Key Violation' error. The same error occurs when using the standard components, you can check it yourself. In this case, the only solution is to set PacketRecords to -1.