问题描述
|
我需要将对客户端发生的对实体所做的更改记录到数据库表中。但是,当我进行更改并检查ChangeTracker属性时,它声称没有发生更改。
[服务]
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
}
[客户]
public EntitySet<SomeEntity> SomeEntities
{
get { return _someEntity; }
set
{
if (_someEntity!= value)
{
_someEntity= value;
OnPropertyChanged(\"SomeEntities\");
}
}
}
因此,如果自我跟踪实体和WCF Ria Services不能一起生活(我怀疑这是事实),那么一个跟踪将如何改变?
解决方法
不要使用Ria服务,而只能使用WCF(不知道它是否有很大的不同...)。首先,您不必执行命令(服务器端)即可开始跟踪实体,这是通过WCF反序列化自动完成的。
[OnDeserialized]
public void OnDeserializedMethod(StreamingContext context)
{
IsDeserializing = false;
ChangeTracker.ChangeTrackingEnabled = true;
}
其次,我知道的是,更改时仅记录SELF跟踪实体的主键和外键属性。对于常驻实体环境中的NORMAL实体则不是这种情况(然后记录了所有更改)。
如果您仔细查看自我跟踪实体,您可能会看到类似以下内容的信息:
[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;
你看得到差别吗?在简单属性Plaats和外键属性LandID之间?它位于`ChangeTracker.RecordOriginalValue(\“ LandID \”,_landID);行中。
对于简单属性,不会记录这些更改(属性本身是偏离路线的更改,以便EF上下文知道如何ApplyChanges和更新数据库)。
可能的想法可能是:
定制T4模板以记录每个属性的原始值
要从基类派生所有实体,您可以在其中放置一些框架来通过响应propertyChanged事件来记录原始值
更新实体时,首先要从数据库中获取原始值并跟踪更改
希望这可以帮助!