📎 Webclip
Avoiding Identity Obsession in .NET with Entity Framework Core
Peter Ritchie follows up an earlier post on Identity Obsession (the practice of pushing a database-required primary key into a Domain entity that doesn’t otherwise need one) with a worked example in EF Core. A Client entity has its own local identity as an object; the SSN the database wants as a primary key is a persistence detail, not part of the domain model, and he shows how to keep it that way.
The mechanism is EF Core’s shadow properties: identifiers configured on the entity type without existing as properties on the C# class itself. The DbContext owns the responsibility of generating and reading that shadow key; the repository owns the domain concern of allocating the actual SSN.
Fichamento#
IEntityTypeConfiguration<Client>declares a shadowIdproperty (GUID stored asvarchar(36)) as the primary key, and a shadowSsnproperty with aHasConversionmapping between theSsnvalue type and its string column representation.- The
Clientclass itself carries no identifier property. It only exposes domain behavior, in this example aChangeNamemethod. DatabaseContextreads and writes the shadow properties throughEntry(client).Property(...), includingGetClientBySsnAsync,GetClientByIdAsync, andAddClientAsync, which sets the shadowIdviaGuid.NewGuid()and the shadowSsnbefore callingSaveChangesAsync.ClientRepositoryimplementsIClientRepository(FindBySsnAsync,SaveAsync,AddAsync,FindClientsAsync) using the Result Pattern instead of exceptions, and is where SSN allocation happens through anISsnRegistrythat reserves a value and commits it only after a successful save.SaveAsyncbranches on EF’sEntityState(Detachedtriggers an add,Modifiedtriggers a save) to route persistence without the caller needing to know which case applies.- Caveat noted in the post: storing raw SSNs is bad practice; the example keeps them in plain text only for clarity, and a real implementation should hash or encrypt the value before persisting it.
