facing an error

This is between XData & Aurelius. I have Aurelius objects and and XData service:

function TXXXService.DO(AAAA, ABBB: string): integer;
var
xxx : TXxx;
lst: TObjectList;
begin
lst := ServerContainer.AureliusManager.ObjManager.Find.Where((Linq['AAA'] = AAAA) and (Linq['BBB'] = ABBB)).List;

if lst.IsEmpty then
begin
xxx := TXxx.Create;
try
xxx.AAA := AAAA;
xxx.BBB := ABBB;
xxx.CCC := TDateTime.NowUTC;
xxx.DDD := TDateTime.NowUTC;
ServerContainer.AureliusManager.ObjManager.Save(xxx);
finally
xxx.Free;
end;
end
else
begin
xxx := lst[0];
xxx.DDD := TDateTime.NowUTC;
ServerContainer.AureliusManager.ObjManager.Update(xxx);
ServerContainer.AureliusManager.ObjManager.Flush;
end;
end;

It gives me some random errors when I call it, i.e.:

Or sometimes access violations.

Am I doing it right?

It's probably an Aurelius thing. I'm beginning to think that if I were to use direct DB access with SQL in these services, it would not have been an issue...

But remarkably, it sometimes works.

PS: It took me an hour yesterday to write code in Aurelius to just do a simple "count(*)" - it really should be improved somehow, it's waaaaay too convoluted as it is.

And another issue I'm running into is that if the server is restarted, the client almost certainly starts throwing exceptions.

PPS: And it was a surprise that TXDataClient was not a TComponent, why is that? It just makes it harder to use.

Couldn't edit previous reply, so delete it and replied again :face_with_raised_eyebrow:

I am not an expert on queries, but the first thing I notice that you use

ServerContainer.AureliusManager.ObjManager.Find.Where...

I think this should read

ServerContainer.AureliusManager.ObjManager.Find.Where

so that it knows what type (table) you're querying.

Not sure what is going on here but I am suggesting

Find < TSomeType >

Yep, thanks, I have that - this editor does swallow things in angle brackets, so my post did not show it.

I think it would not compile otherwise.

But the thing is it starts erroring on things I do not even do, that THttpHeaderInfo is clearly something it does internally.

You should not call xxx.Free if you save it using the manager. When you save, the manager takes control of the object lifetime and will destroy it eventually, leading to a double destroy. That's the cause of your error.

Side note: properly format the code, wrapping the text using triple backslashes (```) or select the text and click the "code" button to format it:

Perfect, thanks!

And when I get the count with:

    CountResult := ServerContainer.AureliusManager.ObjManager.Find<Tyyy>.Where(Linq['AAA'] = Aaaa).Select(TProjections.Sql<Int64>('count(*)')).UniqueValue;
    if Assigned(CountResult) then
      try
        result := CountResult.Values[0];
      finally
        CountResult.Free;
      end;

Does it need to be freed, as I have done above?

And also, if I do:

  ServerContainer.AureliusManager.ObjManager.Update(xxx);

it does not actually change the data in the table, so now I call this next:

  ServerContainer.AureliusManager.ObjManager.Flush;

Is this how it's supposed to be or is there a better way?

Yes, as stated in the documentation: Queries | TMS Aurelius documentation

It's important to note that TCriteriaResult objects are not managed by the TObjectManager , so the retrieved objects must be destroyed. When using ListValues method to retrieve the results, the returned list is a TObjectList object that already has its OwnsObjects property set to true. So destroyed the list should be enough. When using UniqueValue or Open methods, you must be sure to destroy the TCriteriaResult objects.

Yes, as stated in the documentation: Manipulating Objects | TMS Aurelius documentation

As a side note, you can use Aurelius projections for aggregated functions to use Count no need to use a custom SQL projection: