如何使用WCF Ria Services跟踪实体更改

本文关键字:实体 跟踪 Services 何使用 WCF Ria | 更新日期: 2023-09-27 17:58:57

我需要将客户端上对实体所做的更改记录到数据库表中。但是,当我进行更改并检查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不能共存(这正是我所怀疑的),如何跟踪更改?

如何使用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上下文就知道如何应用更改并更新数据库)。

可能的想法是:

  1. 自定义T4模板以记录每个属性的原始值
  2. 从基类派生所有实体,在基类中可以通过响应propertyChanged事件来建立一些记录原始值的框架
  3. 更新实体时,首先从数据库中获取原始值并跟踪更改

希望这能有所帮助!