问题
I need to log changes made to an entity that occur on the client to a database table. However, 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?
回答1:
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:
- To customize the T4 template to record original values for every property
- To derive all entities from a base class where you could lay down some framework for recording original values by responding to propertyChanged events
- When updating the entites, first getting the original values from the database and track the changes
Hope this helps!
来源:https://stackoverflow.com/questions/6332802/how-to-track-entity-changes-with-wcf-ria-services