Add and Delete List of Object

Hi,


I have 2 AureliusDataSet in my Win32 Client, like Master-Detail .
First, I would like to delete all record of detail, in 1 time (no TObject.Delete one by one).
After, I would like to add 100 record by exemple.

Can I write thing like this ?

procedure TForm11.Button3Click(Sender: TObject);
var R: TResultat;
  i: integer;
  RR: TList<TObject>;
begin
  rr := XClient.List(TResultat);
  rr.Clear;
  screen.Cursor := crHourGlass;
  try
    for i := 1 to 100 do
    begin
      R := TResultat.Create;
      R.IdCourse := AureliusDataset1.Current<TCourse>;
      R.Position := i;
      R.Num := IntToStr(100+i);
      RR.Add(R);


  end;
  XClient.Post(RR);
  finally
    screen.Cursor := crDefault;
    rr.Free;
  end;
end;


Maybe i must write somthing in Server to add in one time ?

Indeed, there is no automatic endpoint for adding or deleting multiple entities at once. But you can simply create a service operation (server method) that receive a TList<TResultat> and then process it server side. From client side you build such list the way you are doing and then send it to server method.

Hi Wagner,


That's i looking for.
Have you a litte example server-side to place me on the good way ?

KR

Hi Marc, it's just a regular service operation: http://www.tmssoftware.biz/business/xdata/doc/web/service_operations.html.

Create a parameter of type TList<TResultat> and the list will be available for you server-side. Do the operations you need to do with it.
Hi Wagner,

I've understand but i think i miss important thing :(

On Client :

procedure TFrmClient.btExportClick(Sender: TObject);
var
  Client: TXDataClient;
  MyService: IMAJResutatService;
  SumResult: double;
  i: integer;
  R: TResultat;
begin
  Resultats := TList<TResultat>.Create;
  try
    MyService := XClient.Service<IMAJResutatService>;


    dtsResultat.First;
    i:=0;
    while not dtsResultat.Eof do
    begin
      if i<=Resultats.Count-1 then
        R := Resultats
      else
      begin
        R := TResultat.Create;
        Resultats.Add(R);
        R.IdCourse := AureliusDataset1.Current<TCourse>;
      end;
      R.Position := dtsResultatPosition.Value;
      R.Num := dtsResultatNum.Value;
      R.Nom := dtsResultatNom.Value;
      R.Categorie := dtsResultatCategorie.Value;
      R.Nationalite := dtsResultatCategorie.Value;
      R.TempsTotal := dtsResultatTempsTotalStr.Value;
      R.NbTour := dtsResultatNbTourAffiche.Value;
      dtsResultat.Next;
      inc(i);
    end;




    MyService.MAJ_R(Resultats, dtsResultat.RecordCount);
  finally
    Resultats.Free;
  end;
end;


On Server :

procedure TMAJResutatService.MAJ_R(_Resultats: TList<TResultat>; _RecordCount: integer);
var i,j: integer;
  Id: Variant;
  R: TResultat;
begin
  for i := 0 to _Resultats.Count-1 do
    if Assigned(_Resultats) then
      begin
        TXDataOperationContext.Current.GetManager.SaveOrUpdate(_Resultats);
      end;




  for i := _RecordCount-1 to _Resultats.Count-1 do
    if Assigned(_Resultats) then
    begin
      j := _Resultats.Position;
      R := TXDataOperationContext.Current.GetManager.Find<TResultat>(
        VarArrayOf([_Resultats.IdCourse.IdCourse.ToString, j]));
      if Assigned(R) then
        TXDataOperationContext.Current.GetManager.Remove(R);
    end;


//  TXDataOperationContext.Current.GetManager.Flush;
end;


Note that TResultat joined on TCourse (with IdCourse as TGUID).
and TResultat Id = (TCourse, Position).

"Resultats" is List of TResultat, like results for one race.

On "SaveOrUpdate", i've got Error 500 "ObjectAlreadeyPersistent"
"Canot turn persistent object of class TResultat with id {E00....XXXX],1
The object is already in persystent context".

Where's the problem ?

update OnServer


procedure TMAJResutatService.MAJ_R(_Resultats: TList<TResultat>; _RecordCount: integer);var i,j: integer;  Id: Variant;  R: TResultat;begin  for i := 0 to _Resultats.Count-1 do    if Assigned(_Resultats) then      begin        TXDataOperationContext.Current.GetManager.SaveOrUpdate(_Resultats/[i/]);      end;

The problem is because you probably have many objects of same type, same id, in your tree of objects, and you are trying to save all of them. You cannot have two objects of same class and same id in same manager.

Try using Merge instead of SaveOrUpdate and it should work.

same issue with Merge()

Are all the associations involved with TCascadeType.Merge included? You have to check your object tree, check those associations.

You're right !


I've change my database.
Old one was TCourse Id with GUID, and TResultat had primary key with IdCourse(GUID) and Position (Integer)
Simple is better.
New one has TCourse Id (integer) and TResultat has Id (integer autoinc), and foreign key TCourse (Id).

Now, work perfect !

You're components very very well done Wagner
Very Thank's :)