Part of DKNet.EfCore.DataAuthorization. Use the Quick Start. Its tracked invoice exposes a domain method; try an inaccessible transfer after reading it:
invoice.AssignOwner("tenant-z");
await db.SaveChangesAsync();
Console.WriteLine(invoice.OwnedBy); // tenant-a: reverted without throwing
IOwnedBy exposes a getter-only string OwnedBy; EF-mapped accessors can reach a private setter. An existing non-empty owner on an added entity is preserved. A modified owner is accepted only when unchanged or non-empty and present in GetAccessibleKeys().
| Setting | Type | Default | Effect |
|---|---|---|---|
GetOwnershipKey() |
string? |
Required implementation | Non-empty value stamps blank new owners; null/empty skips creation stamping and audit fallback. |
GetAccessibleKeys() |
ICollection<string> |
See read configuration | Allowed ownership replacements on modified entries. |
CreatedBy/UpdatedBy: the audit-field split| Current user for the save | OwnedBy |
Audit fields on IAuditedProperties |
|---|---|---|
| Provider absent or returns null/empty | Ownership hook | Ownership-key fallback. |
Non-empty ICurrentUserProvider value |
Ownership hook | EfCoreAuditHook supplies the signed-in user. |
Both hooks decide from provider values, independently of registration order. A blank creation identity is filled with UTC time; explicit creation values and modifier/timestamp changes are preserved by the shared AuditPropertyStamper. Audit fallback also applies to audited entries without IOwnedBy; the query filter only targets owned types.
Stamp the current user describes the optional audit provider. The package architecture shows this composition. AddDbContextWithHook attaches the runner; plain AddDbContext needs explicit hook wiring.
ExecuteUpdate, ExecuteDelete, raw SQL and other tracker-bypassing writes do not run this hook. Use async tracked saves for stamping.