更改跟踪 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();
}
我目前使用此方法对谁在对什么实体执行此操作进行一些基本审计。
我为 属性 更改的名称和之前的值以及之后的值制作 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();
}
我目前使用此方法对谁在对什么实体执行此操作进行一些基本审计。