SaveOrUpdate question

I'm working with an local SQLite database that need to be synchronized with data fetched from a remote X-Data server. All entities do have an existing ID. At the first run, local database is empty : it doesn't contains any entity.

What is the best way to save or update these fetched entities ? My first idea was to call Manager.SaveOrUpdate(TEntity) but this is not working because fetched entities does have an assigned ID and doesn't exists in the local SQLite database.

If we look at the TobjectManager.InternalSaveOrUpdate method we can see this :

  // If there is an Id assigned, then update. Otherwise, Save
  if FObjects.HasIdValue(Entity) then
    InternalUpdate(Entity, ProcessedObjs)
  else
    InternalSave(Entity, MasterObj, ProcessedObjs);

Would it be possible to update the SaveOrUpdate method so that no existing entities will be created to ?


I've found a workaround but I don't know if this is the fastest and best way to do it. I'm first searching an existing entity. If found than I merge new data if not I save it :



var
  Assure: TAssures;
  Client: TXDataClient;
  Assures: TList<TAssures>;
begin
  Client := TXDataClient.Create;
  try
    Assure := TAssures.Create;
    try
      Assures := Client.List<TAssures>;
      for Assure in Assures do
        if (Manager.Find<TAssures>.Add(Linq['RefAssure'] = Assure.RefAssure).UniqueResult <> nil) then
          Manager.Merge<TAssures>(Assure)
        else
          Manager.save(Assure);
    except
      if not Manager.IsAttached(Assure) then
        Assure.Free;
      raise;
    end;
  finally
    Client.Free;
    Assures.Free;
  end;
  ShowMessage('Persons retrieved.');
end;

For those interested, I've slightly modified the above code and replaced Merge with Replicate and by calling Flush !


var
  Assure: TAssures;
  Client: TXDataClient;
  Assures: TList<TAssures>;
begin
  Client := TXDataClient.Create;
  try
    Assure := TAssures.Create;
    try
      Assures := Client.List<TAssures>;
      for Assure in Assures do
          Manager.Replicate(Assure);
    except
      if not Manager.IsAttached(Assure) then
        Assure.Free;
      raise;
    end;
  finally
    Manager.Flush;
    Client.Free;
    Assures.Free;
  end;
  ShowMessage('Persons retrieved.');
end;

Yes, Replicate is the most straightforward way in this case. But you don't need to create a TAssures object in the first place, you can remove the "  Assure := TAssures.Create;" line

Thank you Landgraf.