I've seen all the questions out there for tracking changes to an entity, but none of those solutions included navigation properties. Is this even possible? I don't need some SUPER generic solution that just logs everything. I only want things tracked for specific "main" entities. And the audit log is going to be a human readable custom one, so not just some table that has oldData newData like I have seen in the examples on here.
I've gotten it almost to a good point except tracking the navigation properties, I have an Interface on the POCO's service that determines whether I want to track changes, then in my entityService.Save method I have this check:
var trackChangesService = this as ITrackChangesService<TClass>;
if (trackChangesService != null)
{
      TClass oldEntity = Repository.GetOldEntity(entity);
      trackChangesService.SaveChanges(entity, oldEntity);
}
The save changes method is what the ITrackChanges interface exposes and will have custom logic on a per entity basis (this includes email notifications, etc.), but the problem is I can't propertly get the oldEntity. Currently the method looks like this:
public TClass GetOldEntity(TClass entity)
    {
        //DbEntityEntry<TClass> oldEntry = Context.Entry(entity);
        ////oldEntry.CurrentValues.SetValues(oldEntry.OriginalValues);
        //var values = oldEntry.OriginalValues;
        //return (TClass)oldEntry.GetDatabaseValues().ToObject();
        return Context.Set<TClass>().AsNoTracking().FirstOrDefault(x => x.Id == entity.Id);
    }
You can see the code I have been playing with. I can get the regular properties old and new values fine, but the navigation properties do not carry over. But I need this information, say for instance I am editing a user and on the edit user screen, groups can be removed and added. When the save button is clicked, it performs those updates.
So my update view look like this:
private UserSaveModel Update(Guid id, UserSaveModel userSaveModel)
    {
        User user = _userService.GetOne(x => x.Id == id);
        user = _userService.ConvertFromSaveModel(userSaveModel, user);
        _userService.Save(user);
        return userSaveModel;
    }
I guess one way to look at the problem is, I am adjusting the values on the entity on the context in .ConvertFromSaveeModel() on the existing user record, including the navigation properties, so once I call save, that old navigation property data is gone.
Is there anyway to get original navigation property information for an entity using this workflow? If not, how can I change the workflow to make this possible? If I don't query the user object at the beginning and instead make one from scratch, some data that may not be exposed in the viewModel won't pass over, so I am not sure that will work. Any other suggestions? Maybe clone the entity and use that as original before I made changes? Does that carry over navigation properties?