更改跟踪 Entity framework

Change Tracking Entity framework

我为 属性 更改的名称和之前的值以及之后的值制作 table
我如何使用更改跟踪来存储此 table 中的更改?

您可以使用更改跟踪来跟踪操作、更改的列和新值。但是,不可能从更改跟踪中获取旧值。 SQL Server 2016 提供了新功能 "Change data capture",它为您提供了有关 update/delete 发生之前旧值的所需信息(请参阅 https://msdn.microsoft.com/en-us/library/bb933994.aspx)。

如果您无法访问 SQL Server 2016,可以按照以下方法配置更改跟踪:

  • 在数据库激活

    ALTER DATABASE <YourDatabase> f.e. DeviceDatabase
    SET CHANGE_TRACKING = ON  
    (CHANGE_RETENTION = 2 DAYS, AUTO_CLEANUP = ON) 
    
  • 为您需要的 tables

    激活更改跟踪
    ALTER TABLE <YourTable> f.e. Devices  
    ENABLE CHANGE_TRACKING  
    WITH (TRACK_COLUMNS_UPDATED = ON)  
    
  • 设置数据库作业,它将每分钟、每小时、每天(您需要)将更改信息复制到您的自定义 table

    DECLARE @minversion bigint;
    SET @minversion = (SELECT MinVersion = CHANGE_TRACKING_MIN_VALID_VERSION(OBJECT_ID('Devices')) )
    
    SELECT SYS_CHANGE_COLUMNS, e.Id FROM
    CHANGETABLE(CHANGES Devices, @minversion) AS C
    LEFT OUTER JOIN Devices AS e  
    ON e.Id = c.Id;  
    
  • 要获取已更改列的最新值,您可以试试这个(但要注意同一行的多次更新。您只能获取最新值)。

    CHANGE_TRACKING_IS_COLUMN_IN_MASK
    (COLUMNPROPERTY(OBJECT_ID('Devices'), 'Id', 'ColumnId')
    ,c.sys_change_columns)
    

这将 return 如果列已更改,则为 1,否则为 0。您可以为 table 的每一列添加它并加入值 = 1,然后将该值添加到您的查询中。

最后,我只建议在您的表上使用存储过程Update/Insert/Delete。在那些你可以很容易地插入你想要存储的关于你的自定义 table 中的变化的所有信息。 如果您有 SQL Server 2016,请最终尝试我上面提到的方法。

实际上,如果您在数据上下文 class 中覆盖 SaveChanges() 方法,您就可以访问 ChangeTracker。这为您提供了上下文当前跟踪的所有实体及其 EntityState(如果它们是 added/modified/deleted/unchanged 等)。

在这里您可以获得 DbEntityEntry class 并从中获取实体的当前值 and/or 如果实体处于修改状态,则它的先前值。

public override int SaveChanges()
{
    var allTrackedEntities = this.ChangeTracker.Entries().ToList();

    return base.SaveChanges();
}

我目前使用此方法对谁在对什么实体执行此操作进行一些基本审计。