Soft-delete & Query Filters
MessageEntity carries two soft-delete fields:
IsDeleted(bool) — set totruewhen the message is deleted.DeletedAt(DateTimeOffset?) — the timestamp of the deletion.
Deleting a message sets these fields rather than removing the row from the database.
The row survives physically, which is required to keep the History
foreign key valid: MessageHistoryEntity holds a real FK to MessageEntity, and
hard-deleting the message row would cascade-delete its history — including the row
that logged the deletion.
Default query filter
ApplyMessagesModule() installs a global EF Core query filter that hides
soft-deleted messages in all queries by default:
// filter ON — soft-deleted messages are invisible (default)
modelBuilder.ApplyMessagesModule();
Disabling the filter at startup
If you want all messages — including soft-deleted ones — to be returned by every query, disable the filter when applying the module:
// filter OFF — soft-deleted messages appear in all queries
modelBuilder.ApplyMessagesModule(filterDeleted: false);
Per-query escape hatch
To read soft-deleted rows on a single query while keeping the global filter enabled,
use the standard EF Core IgnoreQueryFilters() extension:
var all = db.Messages.IgnoreQueryFilters().ToList();
This bypasses the filter for that query only. All other queries continue to hide soft-deleted messages.