I'm trying to implement a change auditing system at the context level using EF4 (database first). I'm overriding SaveChanges
and capturing entities that have a state of Added
, Deleted
, or Modified
from the context's ObjectStateManager
. This normally works, but I've encountered an issue where none of the entities have this state (including entities that I have changed in code), but the context does have changes to the database. I've gone so far as to look at the list of entries with Unchanged
as the state, and my modified entity is in that list.
The only complication that I can see is that I'm using self-tracking entities (as this is a WCF service that ordinarily sends these STE's down to the client for changes, then the client passes the modified STE's back up to persist the changes). What seems to be happening is that objects that are retrieved on the server and modified directly there (rather than being passed to the client and using the STE's ObjectChangeTracker
) are not being marked as Modified
. Is this normal/expected behavior? If this is the case, then clearly the context is using something other than the ObjectStateManager
to determine what changes to persist to the database, as the changes are being made.
How can I detect these changes and keep track of them? Does anyone know what it is that the context is using to track changes? I had always assumed it was the ObjectStateManager
, but that seems not to be the case.
Turns out the issue is with the saveOptions
. Since these options (by default) include DetectChangesBeforeSave
, the context was calling DetectChanges
internally, which picked up the modifications and properly set the state of the ObjectStateEntry
. By adding this to my audit routine:
if ((options & SaveOptions.DetectChangesBeforeSave) ==
SaveOptions.DetectChangesBeforeSave)
{
DetectChanges();
options ^= SaveOptions.DetectChangesBeforeSave;
}
It now works correctly.