Why EntityBase and IObjectState?

May 12, 2014 at 5:15 PM
First thank you to the author and contributors, I really like this solution.

I am troubled by the necessity of all entity objects in the model to implement EntityBase and IObjectState. Why can't the state and changes to the state be tracked by the implementation of DataContext? I figure this way the model does not have to know about its persistence state which leads to better decoupling and we now also store the persistence state tracking in the persistence layer so higher cohesion there.

As a trial I removed EntityBase and IObjectState and implemented the following in the DataContext:
public class DataContext : DbContext, IDataContext, IDataContextAsync
{
    private readonly ObjectIDGenerator _idGenerator;
    private readonly IDictionary<Int64, ObjectState> _objectStates;
        private readonly Guid _instanceId;

    public DataContext(string nameOrConnectionString)
        : base(nameOrConnectionString)
    {
        _idGenerator = new ObjectIDGenerator();
        _objectStates = new Dictionary<long, ObjectState>();
        _instanceId = Guid.NewGuid();
        Configuration.LazyLoadingEnabled = false;
        Configuration.ProxyCreationEnabled = false;
    }
        
// also added this method to the IDataContext interface
    public void AttachState(object entity, ObjectState entityState)
    {
        this.setObjectState(entity, entityState);
    }

    private void setObjectState(object objectContext, ObjectState state)
    {
        lock (_idGenerator) // thread safe
        {
            bool isFirstTime;
            var id = _idGenerator.GetId(objectContext, out isFirstTime);
            _objectStates[id] = state;
        }
    }
    private ObjectState getObjectState(object objectContext)
    {
        lock (_idGenerator) // thread safe
        {
            bool isFirstTime;
            var id = _idGenerator.GetId(objectContext, out isFirstTime);
            if (isFirstTime || !_objectStates.ContainsKey(id))
                _objectStates[id] = ObjectState.Unchanged;
            return _objectStates[id];
        }
    }
// rest of code
}
The rest of DataContext is the same with the exception of all calls to get and set the entity object's state. All previous calls to get/set object persistence state now call (directly or indirectly) DataContext:AttachState and DataContext:getObjectState. I tested this locally and seems to work fine.

Is this something that was already thought of but axed for particular reason(s)?
Can anyone give me a good reason not to do this?
Finally, is this something that you would like to see added to a new Fork in the source code?

Thank you again,
-Igor
May 12, 2014 at 9:29 PM
Marked as answer by lelong37 on 5/12/2014 at 1:29 PM