开发者

How to track entity changes with WCF Ria Services?

I need to log changes made to an entity that occur on the client to a database table. Howeve开发者_StackOverflowr, when I make changes and inspect the ChangeTracker property, it claims that no changes have occurred.

[Service]

    private static readonly ISomeDao someDao = DataAccess.SomeDao;
    [Query]
    public List<SomeEntity> GetSomeEntites(int someId)
    {
        var entities = someDao.GetSomeEntites(someId);
        entities.ForEach(e => e.StartTracking());
        return entities;
    }

    [Update]
    public void UpdateSomeEntity(SomeEntity entity)
    {
        // inspect entity.ChangeTracker.OriginalValues.... nothing
        entity.StopTracking();
        // inspect entity.ChangeTracker.OriginalValues.... nothing
        ...
        // Update log table 
    }

[Client]

    public EntitySet<SomeEntity> SomeEntities
    {
        get { return _someEntity; }
        set
        {
            if (_someEntity!= value)
            {
                _someEntity= value;
                OnPropertyChanged("SomeEntities");
            }
        }
    }

So, if, self-tracking entities and WCF Ria Services can't live together (which is what I'm suspecting), how does one track changes?


Don't work with Ria services but solely with WCF (don't know if it makes much difference...). First of all you don't have to execute the command (server-side) to StartTracking the entities this is done automatically with deserializing by WCF.

[OnDeserialized]
public void OnDeserializedMethod(StreamingContext context)
{
  IsDeserializing = false;
  ChangeTracker.ChangeTrackingEnabled = true;
}

Second what I know is that only primary- and foreign key properties of a SELF tracking entity are recorded when changed. this is not the case for NORMAL entities that keep living in an entity context (then all changes are recorded).

If you take a closer look at a Self-Tracking-Entity you might see something like this:

    [DataMember]
    public string Plaats
    {
        get { return _plaats; }
        set
        {
            if (_plaats != value)
            {
                _plaats = value;
                OnPropertyChanged("Plaats");
            }
        }
    }
    private string _plaats;

    [DataMember]
    public int LandID
    {
        get { return _landID; }
        set
        {
            if (_landID != value)
            {
                ChangeTracker.RecordOriginalValue("LandID", _landID);
                if (!IsDeserializing)
                {
                    if (Land != null && Land.ID != value)
                    {
                        Land = null;
                    }
                }
                _landID = value;
                OnPropertyChanged("LandID");
            }
        }
    }
    private int _landID;

Do you see the difference? between the simple property Plaats and the Foreign key property LandID? It's in the line `ChangeTracker.RecordOriginalValue("LandID", _landID);

For simple properties these changes are not recorded (the properties themseklves are off-course changed, so that EF context knows how to ApplyChanges and update the database).

Possible ideas could be:

  1. To customize the T4 template to record original values for every property
  2. To derive all entities from a base class where you could lay down some framework for recording original values by responding to propertyChanged events
  3. When updating the entites, first getting the original values from the database and track the changes

Hope this helps!

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜