Skip to content

Serialize the deleted list only when it is not empty - #4963

Merged
rockfordlhotka merged 2 commits into
mainfrom
issue-4266/analyze-empty-lists
Oct 16, 2026
Merged

rockfordlhotka merged 2 commits into
mainfrom
issue-4266/analyze-empty-lists

Conversation

@rockfordlhotka

Copy link
Copy Markdown
Member

Closes #4266

Summary

BusinessListBase, BusinessBindingListBase and BusinessDocumentBase skipped the deleted list during serialization only when the field was null. But IsDirty, IsBusy, CopyState and Deserialized() all read the lazily created DeletedList accessor. So in practice every list, even one fresh from Create, carried an empty deleted list in every MobileFormatter payload.

This change serializes the deleted list only when it contains items, which is how BusinessRules already handles _brokenRules. OnSetChildren resets the field to null when the payload has no deleted list, and the DeletedList accessor recreates it on demand. There is no public API change, and the accessor is still never null.

See the analysis comment on #4266 for why the null-vs-empty question is otherwise already settled.

Payload size (MobileFormatter, orders list with line-item child lists)

Graph Lists Before After Saved
1 order, 0 lines 2 1,958 1,646 15.9%
10 orders × 3 lines 11 18,116 17,417 3.9%
50 orders × 3 lines 51 84,676 82,257 2.9%
200 orders × 5 lines 201 479,976 471,107 1.8%

That works out to about 44 bytes per list, or 156 bytes for the first list of a type. Serialization time differences were within noise.

Tests

Added DeletedListSerializationTests, with three tests for each of the three list types:

  • An empty deleted list (created by reading IsDirty) is not written to the payload.
  • A non-empty deleted list round-trips, and the clone is dirty.
  • A clone without a deleted list can still remove items, and ContainsDeleted and IsDirty behave correctly.

The full csla.test.sln suite (TestCategory!=SkipOnCIServer) passes on net10.0 and net11.0.

🤖 Generated with Claude Code

rockfordlhotka and others added 2 commits October 16, 2026 00:32
BusinessListBase, BusinessBindingListBase and BusinessDocumentBase
skipped the deleted list during serialization only when it was null.
IsDirty, IsBusy, CopyState and Deserialized all read the lazily
created DeletedList, so in practice every list carried an empty
deleted list in every MobileFormatter payload.

The deleted list is now serialized only when it contains items,
matching how BusinessRules handles the broken rules collection.
OnSetChildren resets the field to null when the payload has no
deleted list, and the DeletedList accessor recreates it on demand.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

The focused changes preserve populated deleted lists and lazy initialization, with regression coverage and no blocking issues identified.

0 open findings

What changed in this PR

Reduces MobileFormatter payload sizes by omitting empty deleted lists across CSLA’s three editable collection types, addressing #4266.

Changes:

  • Serialize deleted lists only when populated.
  • Reset omitted deleted-list fields to null, preserving lazy initialization.
  • Add nine regression tests and document the payload reduction.
File Description
Source/​tests/​Csla.test/​Serialization/​DeletedListSerializationTests.cs Tests omission, populated round-trips, and deletion after cloning.
Source/​Csla/​BusinessListBase.cs Omits empty deleted lists and resets absent fields.
Source/​Csla/​BusinessDocumentBase.cs Applies the same serialization behavior to documents.
Source/​Csla/​BusinessBindingListBase.cs Applies the same serialization behavior to binding lists.
releasenotes.md Documents the payload-size improvement.

🧠 Review effort: Balanced


💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@rockfordlhotka
rockfordlhotka merged commit d2f5240 into main Oct 16, 2026
4 checks passed
@rockfordlhotka
rockfordlhotka deleted the issue-4266/analyze-empty-lists branch October 16, 2026 15:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Consider whether lists can be initialized to empty instead of null

2 participants