【发布时间】:2016-09-15 11:13:06
【问题描述】:
我为更改的属性名称和之前的值和之后的值创建表
我如何使用更改跟踪将更改存储在此表中?
【问题讨论】:
-
你已经尝试过了吗?
-
你能分享一下它的代码吗?
标签: c# entity-framework change-tracking
我为更改的属性名称和之前的值和之后的值创建表
我如何使用更改跟踪将更改存储在此表中?
【问题讨论】:
标签: c# entity-framework change-tracking
您可以使用更改跟踪来跟踪操作、更改的列和新值。但是,无法从变更跟踪中获取旧值。 SQL Server 2016 提供了新功能“更改数据捕获”,它可以在更新/删除发生之前为您提供有关旧值的所需信息(请参阅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)
为您需要的表激活更改跟踪
ALTER TABLE <YourTable> f.e. Devices
ENABLE CHANGE_TRACKING
WITH (TRACK_COLUMNS_UPDATED = ON)
设置一个数据库作业,它将每分钟、每小时、每天(您需要的)将更改信息复制到您的自定义表中
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)
如果 Column 更改,则返回 1,否则返回 0。您可以为表的每一列添加它并加入 value = 1,然后将该值添加到您的查询中。
最后,我只建议使用存储过程来更新/插入/删除您的表。在这些信息中,您可以轻松地插入要存储的有关自定义表中更改的所有信息。 如果您有 SQL Server 2016,请尝试我上面提到的方法。
【讨论】:
实际上,如果您在数据上下文类中覆盖SaveChanges() 方法,您可以访问ChangeTracker。这将为您提供当前由上下文跟踪的所有实体及其EntityState(如果它们被添加/修改/删除/未更改等)。
在这里,您可以获取DbEntityEntry 类,如果实体处于修改状态,则从中获取实体的当前值和/或之前的值。
public override int SaveChanges()
{
var allTrackedEntities = this.ChangeTracker.Entries().ToList();
return base.SaveChanges();
}
我目前使用这种方法对谁在对哪个实体做一些基本的审计。
【讨论】:
public partial class MyExtendedDbContext。