XDataClient, Aureliusdataset and DbLookUpCombo

Hey,

i've got a Problem with Aurelius and TDbLookUpComboBox.
The ComboBox is empty on initial Load of Data.
I receive the Data from a XDataClient and when i DropDown and select a Value, the TDbLookUpComboBox is filled correctly and saves the Data as it sould.
But i want to Display the Data on receiving them so that it wont look like the Field is empty.

What i tried so far:

  • Called "Locate" on the ListDatabase
  • Changed ListItemindex to -1, 0 and 1 without changes
  • First opened and populate the ListDatabases and then the TargetDatabase

How i receive the Data:

  adLieferant.Close; //Listdata
  adLieferant.ObjectClass:=TLieferant;
  adLieferant.SetSourceList(dmMain.MainXDClient.List<TLieferant>(
        CreateQuery.From(TLieferant)
      .QueryString
      ));
  adLieferant.Open;

  adArtikel.ObjectClass:=TArtikel; //TargetData
  if not ArtikelGuid.IsEmpty then  adArtikel.SetSourceObject(dmMain.MainXDClient.Get<TArtikel,TGuid>(ArtikelGuid))
  else adArtikel.SetSourceList(dmMain.MainXDClient.List<TArtikel>(
        CreateQuery.From(TArtikel)
      .Top(10)
      .QueryString
      ));
  adArtikel.Open;

  adLieferant.Locate('self',adartikel.FieldByName('Lieferant_nr').AsString,[]);

I set the KeyField to "Self".
I used the same code using an Aureliusmanager, accessing the Database directly, which worked correctly.
But for my scenario i need to get the Data from an XDataServer and can't use the Aureliusmanger to handle my Object.

I hope i could describe my Problem.

Kind regards,

The difference here is that TXDataClient doesn't manage unique instances. So the list of TLieferant instances you get from the first List call is different from the list of TLieferant objects you get in the second call.

In your last Locate call, try to locate the record by a secondary unique field, for example, the lieferant id or something similar.

Here are a few insights:

Ok, i got the problem solved by changing

  • Keyfield to "nr" instead of "self"
  • Datafield from Lieferant_nr (Entity) to Lieferant_nr.nr (uniqueidentifier)

When i want to post changes made in the comboboxes to the XdataServer i'm using the following Code:

  Artikel:=adArtikel.Current<TArtikel>;
  Artikel.Lieferant_nr:=adLieferant.Current<TLieferant>;
  Artikel.Art_nr:=adArt.Current<TArt>;
  dmMain.MainXDClient.Post(Artikel);

That is working , but i wonder if it's the most effective way to post changes to the Main Entity. When i used the "Aurelius Manager Apporach" in a former application, i didn't have to explicit update every foreign key, because i used self as Key Field.
Am i guessing right, that this is not possible to achieve this with XData because XData doesn't manage unique instances?

Thanks for your help.
Kind regards,

Your approach is fine, one way to do it. Another would be keeping Self as key field, but then using Locate after loading the record, as you were initially trying to do. But doing a locate using nr field, not self.

I tried, changing the keyfield to self and the datafield to Lieferant_nr and used

adLieferant.Locate('nr',adartikel.FieldByName('Lieferant_nr.nr').AsString,[]);

which is not working. The Combo Box is empty when i open the Form.
Could it be because the pointer
adArtikel.Lieferant_nr
is not the same as
adLieferant.self
?

Before you call Locate, is there a value for field adartikel.FieldByName('Lieferant_nr.nr').AsString, or is it empty? Is dataset adLieferant already loaded?

Yes.
I First open and load the Detail Table adLieferant.
Then i open the Table adArtikel.

  adLieferant.Close;
  adLieferant.ObjectClass:=TLieferant;
  adLieferant.SetSourceList(dmMain.MainXDClient.List<TLieferant>(
        CreateQuery.From(TLieferant)
      .QueryString
      ));
  adLieferant.Open;

  adArtikel.Close;
  adArtikel.ObjectClass:=TArtikel;
  if not ArtikelGuid.IsEmpty then  adArtikel.SetSourceObject(dmMain.MainXDClient.Get<TArtikel,TGuid>(ArtikelGuid))
  else adArtikel.SetSourceList(dmMain.MainXDClient.List<TArtikel>(
        CreateQuery.From(TArtikel)
      .Top(10)
      .QueryString
      ));
  adArtikel.Open;

  adLieferant.Locate('nr',adArtikel.FieldByName('Lieferant_nr.nr').AsString,[]);

I can't tell what's going on. I'd appreciate if you could send me a small compilable project using SQLite reproducing the issue, then we can better investigate what's going on and provide you with solutions or explanations.

Can i send you a Zip file per Email?

Sure. Even better if you can send it as a private message.

Please make sure it uses SQLite and no other 3rd party components. Thank you.

Ok, now seeing the project I see that there are additional steps to complete it. Please add this:

  if adLieferant.Locate('nr',adArtikel.FieldByName('Lieferant_nr.nr').AsString,[]) then
  begin
    adArtikel.Edit;
    adArtikelLieferant_nr.AsObject := adLieferant.Current<TLieferant>;
  end;

Thank you. Worked

1 Like

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.