Skip to content

Commit 10cd44d

Browse files
committed
no-mistakes(document): Sync field.map docs to final emission; fix CS8605s
1 parent 59590f0 commit 10cd44d

3 files changed

Lines changed: 20 additions & 3 deletions

File tree

CHANGELOG.md

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,16 @@ It now emits an explicit jsonb column type plus a shared converter/comparer pair
5555
entities, read-only projections and flattened value-object members alike. The comparer is
5656
load-bearing, not decoration: EF snapshots a value-converted property by reference, so a
5757
converter alone would leave an in-place `entity.Labels["k"] = v` undetected and the UPDATE
58-
would never fire.
58+
would never fire. Two details of the emitted shape: the property's NULLABILITY follows the
59+
column — a `@required` map is a non-null dictionary with an empty-dictionary initializer,
60+
any other map a nullable dictionary with no initializer, because the migration's column is
61+
nullable by default and a non-nullable property over it makes EF Core 8 skip the shaper's
62+
NULL check (one NULL cell — a row written by another port, or before the field existed —
63+
would 500 every read arm), and NULL stays distinct from a present `{}`. And the shared
64+
serializer options carry a `JsonStringEnumConverter`, so a `field.enum` member of the map's
65+
value object persists as its member SYMBOL — the rule the owned-`field.object` jsonb column
66+
already follows; System.Text.Json's default int ordinal is a value no sibling port writes
67+
for the same declared field.
5968

6069
**Scope.** No runtime persistence layer reads or writes a map except Python's
6170
`ObjectManager`, and no persistence- or api-contract-conformance corpus exercises

server/csharp/MetaObjects.Codegen.Tests/MapFieldCodegenTests.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -267,9 +267,9 @@ public void MapJsonb_comparer_hash_and_snapshot_tolerate_a_null_dictionary()
267267
// A null map hashes to a stable constant and snapshots as null, on BOTH value-type
268268
// arms -- Hash used to dereference v.Count and the scalar Snap arm passed v to the
269269
// Dictionary copy constructor, so a null map threw inside EF change tracking.
270-
Assert.Equal(0, (int)InvokeLambda(scalar, "HashCodeExpression", (object?)null));
270+
Assert.Equal(0, (int)InvokeLambda(scalar, "HashCodeExpression", (object?)null)!);
271271
Assert.Null(InvokeLambda(scalar, "SnapshotExpression", (object?)null));
272-
Assert.Equal(0, (int)InvokeLambda(objectValued, "HashCodeExpression", (object?)null));
272+
Assert.Equal(0, (int)InvokeLambda(objectValued, "HashCodeExpression", (object?)null)!);
273273
Assert.Null(InvokeLambda(objectValued, "SnapshotExpression", (object?)null));
274274

275275
// Semantics beyond null handling are unchanged: entry-wise order-independent

server/csharp/MetaObjects.Codegen/Generators/DbContextGenerator.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -714,6 +714,14 @@ private static string MapValueTypeRef(MetaField f, GenContext ctx)
714714
/// <c>EqualityComparer&lt;T&gt;.Default</c> with no serialization at all, while a value-object
715715
/// value still falls through to a JSON compare because the generated POCO is a class and
716716
/// compares by reference. The snapshot deep-copies only when the value type needs it.</para>
717+
/// <para>The shared <c>Options</c> instance the helper emits carries a
718+
/// <c>JsonStringEnumConverter</c> so a <c>field.enum</c> member of the map's value object
719+
/// serializes as its member SYMBOL — the rule <see cref="JsonEnumConversions"/> states for
720+
/// the owned-<c>field.object</c> jsonb path, for the same reason: System.Text.Json's
721+
/// default is the enum's int ORDINAL, which no sibling port writes for the same declared
722+
/// field, and <c>@intValueMap</c> is a column-storage concern that reaches nothing inside
723+
/// a JSON document. One shared instance serves the converter and the Eq/Snap JSON arms,
724+
/// so every arm encodes enums identically.</para>
717725
/// <para>Fully qualified throughout: the generated file's usings are a fixed set
718726
/// (<see cref="EmitUsings"/>), and widening it would change byte-identical output for
719727
/// every model.</para>

0 commit comments

Comments
 (0)