persistence records carry data: ClientData/OrderData + domain->persistence mappers
The fake DbContext now stores data-only DbBase subclasses (renamed from the identity-only Shadow wrappers) and refreshes rows in place on re-Save; the object graph is flattened to ids in storage. yak: data-carrying-persistence-records-orderdataclientdata-mappers-tb3a
This commit is contained in:
+40
-4
@@ -1,13 +1,21 @@
|
||||
namespace After;
|
||||
|
||||
/// <summary>
|
||||
/// Hand-written mappers between the plain domain and the DTOs (no AutoMapper —
|
||||
/// the mapping code is part of the illustration). Each public method maps in
|
||||
/// exactly one direction and never mutates its input.
|
||||
/// Hand-written mappers out of the plain domain (no AutoMapper — the mapping
|
||||
/// code is part of the illustration). Each public method maps in exactly one
|
||||
/// direction and never mutates its input. Two families, two destinations:
|
||||
/// <list type="bullet">
|
||||
/// <item><see cref="ClientDto"/>/<see cref="OrderDto"/> — transport to the
|
||||
/// WebApp;</item>
|
||||
/// <item><see cref="ClientData"/>/<see cref="OrderData"/> — the data-only
|
||||
/// records the persistence framework stores.</item>
|
||||
/// </list>
|
||||
///
|
||||
/// The <c>Client.Orders</c> / <c>Order.Client</c> back-reference cycle is
|
||||
/// resolved with a reference-identity cache: the same instance maps to the
|
||||
/// same DTO (and back), so the graph terminates and stays consistent.
|
||||
/// same DTO (and back), so the graph terminates and stays consistent. The
|
||||
/// persistence mapping needs no cache: records reference each other by id,
|
||||
/// not by object, so the graph is flattened and cannot cycle.
|
||||
/// </summary>
|
||||
public static class Mappers
|
||||
{
|
||||
@@ -99,4 +107,32 @@ public static class Mappers
|
||||
seen[dto] = order;
|
||||
return order;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// Domain -> persistence (data-only records; graph flattened to ids)
|
||||
// ------------------------------------------------------------------
|
||||
|
||||
/// <summary>Map a <see cref="Client"/> to its persistence record <see cref="ClientData"/>.</summary>
|
||||
public static ClientData ToClientData(Client client)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(client);
|
||||
return new ClientData { Id = client.Id, Name = client.Name };
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Map an <see cref="Order"/> to its persistence record <see cref="OrderData"/>:
|
||||
/// the object graph is flattened — <see cref="Order.Client"/> becomes the
|
||||
/// <see cref="OrderData.ClientId"/> foreign key (empty when the order has
|
||||
/// no client, or when that client has not been saved yet).
|
||||
/// </summary>
|
||||
public static OrderData ToOrderData(Order order)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(order);
|
||||
return new OrderData
|
||||
{
|
||||
Id = order.Id,
|
||||
Description = order.Description,
|
||||
ClientId = order.Client?.Id ?? Guid.Empty,
|
||||
};
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user