I was wondering if it possible to get the code that was changed with fix #67963. I have the following situation. I’m having the same issue as this question:
The problem I’m having is that I’m in the middle of migrating our app from Delphi 7/XE (client is in D7 and server is in XE) and RO/DA version 6.0.45.821, to Delphi 10, RO/DA version 8.3.91.1167. I still have a long way to go on this migration, so I’m stuck with version 6.0.45.821 on the server side. And I’m working on a new ASP.NET MVC web app that is using version 8.3.91.1167 with LINQ against the Delphi 6.0.45.821 server, but I’m seeing that null values are not being changed on the server.
So if I could get the changes made for this fix, perhaps I could implement those changes in our 6.0.45.821 server and get this problem out of the way.
Open RemObjects DataAbstract solution and change Delta.pas file from:
method Delta.RemoveUnnecessaryChanges();
function IsNotRealChange(change: DeltaChange): Boolean;
begin
if not ((change.Status = ChangeStatus.Pending) and (change.Type = ChangeType.Update)) then
exit false;
for i: Int32 := 0 to change.Count-1 do begin
if assigned(change.NewValues[i]) then begin
if not change.NewValues[i].Equals(change.OldValues[i]) then
exit false;
end
else begin
if assigned(change.OldValues[i]) then
exit false;
end;
end;
exit true;
end;
begin
var lToDelete: System.Collections.Generic.List<DeltaChange> := new System.Collections.Generic.List<DeltaChange>;
for each lChange: DeltaChange in Self.Items do begin
if IsNotRealChange(lChange) then lToDelete.Add(lChange);
end;
for each lChange: DeltaChange in lToDelete do
Self.Items.Remove(lChange);
end;
to
method Delta.RemoveUnnecessaryChanges();
function IsNotRealChange(change: DeltaChange): Boolean;
begin
if not (change.Status = ChangeStatus.Pending) and (change.Type = ChangeType.Update) then
exit false;
for i: Int32 := 0 to change.Count-1 do begin
if assigned(change.NewValues[i]) then begin
if not change.NewValues[i].Equals(change.OldValues[i]) then
exit false;
end
else begin
// For full (ie non-reduced) Delta NewBalue[i] set to null always means that change should be applied to the database,
// regardless of the OldValues[i] value
if (not self.IsReduced) or assigned(change.OldValues[i]) then
exit false;
end;
end;
exit true;
end;
begin
var lToDelete: System.Collections.Generic.List<DeltaChange> := new System.Collections.Generic.List<DeltaChange>(self.Items.Count);
for each change: DeltaChange in self.Items do begin
if IsNotRealChange(change) then
lToDelete.Add(change);
end;
for each change: DeltaChange in lToDelete do
self.Items.Remove(change);
end;
Rebuild the assembly and add corresponding reference to your project.
Thank you! This helped me track down the problem. Since I’m working against a Delphi server, I have to use UseDynamicSelect = true and UseDynamicWhere = true in the LinqRemoteDataAdapter. The problem is caused because setting UseDynamicSelect = true was sending UseReducedDelta = true to the server, regardless of the SendReducedDelta of the data streamer (which I had set to false). Setting UseDynamicSelect to false solved the problem.
This leads me to a question to the Remobjects experts:
In this case, I’m doing a full record change, so setting UseDynamicSelect to false (and therefore, UseReducedDelta to false) helps me deal with this problem of setting string fields to null in the delta. But what if I’m only updating a few fields of a record, and some of those fields are strings that can be set to null? If I set UseDynamicSelect to true, the null strings will be deleted from the delta.
where aCompany is a new instance with no old values. To be able to update string fields to null when using a reduced delta, do I have to keep the old object, for example, in the session, and then retrieve it on the Post action? Or is there a better way to do this not involving the session and not having to retrieve the record from the database again just to update it?