LinqToSQL 和审计更改的字段

Posted

技术标签:

【中文标题】LinqToSQL 和审计更改的字段【英文标题】:LinqToSQL and auditing changed fields 【发布时间】:2009-05-03 14:18:16 【问题描述】:

这是 LinqToSQL 中的另一个问题,我确信我一定错过了某个地方,因为 O/R 设计器的行为让我非常困惑......

我的 LinqToSQL 表有一个基类,我称之为LinqedTable。我已经成功地使用反射来获取后代类的所有属性并执行其他标准操作。

现在我想对我的表进行一些自动审计,以便每当插入或删除LinqedTable 记录或字段值更改时,我都会将记录插入审计表,详细说明更改类型,字段名称,以及保存前和保存后的值。

我想我可以使用PropertyChanging 事件来做到这一点,在保存之前跟踪所有更改的属性,然后在每次SubmitChanges() 调用之后清除更改集合。但是 - 出于某种奇怪的原因,O/R 设计器生成的代码没有在 PropertyChanging 事件中为您提供属性名称 - 它发送一个空字符串! (WHY?!)它确实PropertyChanged 事件中发送了属性名称,但是对于我来说获取原始值已经太晚了。

我想使用 OnLoaded() 部分方法来获取所有属性的所有原始值 - 但根据定义,这是私有的,我需要在基类中访问该方法。即使我使用反射来获取该方法,这也意味着我必须为我的每个表实现另一半部分方法,这有点违背了继承的目的!

我也无法在 DataContext 中找到任何合适的方法来使用或覆盖。

那么,您会建议什么来使此审核功能正常工作?

【问题讨论】:

【参考方案1】:

您可以在 DataContext 上使用 GetChangeSet 来检索在上下文中的所有表上发生的更新、插入和删除的列表。您可以使用 ITable.GetOriginalEntityState 来检索已更改实体的原始值。但是,当您检索已删除或更新记录的原始值时,关联将不可用,因此如果您需要处理相关实体,您将不得不仅依赖该区域中的外键值。您可以使用 ITable.GetModifiedMembers 帮助仅检索已更改的值。

【讨论】:

【参考方案2】:

请原谅我的回答可能很愚蠢,但是如何使用触发器(如果您使用 SQL Server 2005 或 2008 标准)直接在 SQL Server 中进行审计,或者使用 SQL Server 2008 Enterprise 中的更改跟踪工具?

【讨论】:

只是一个哲学问题:如果可以的话,我不喜欢将业务逻辑放在数据层中。我想这是否是“业务逻辑”是有争议的,但无论如何我喜欢在源代码管理中管理代码,在那里我可以看到它。 我也不是,但在这种情况下,我不敢苟同。对我来说,这不是真正的业务逻辑。您当然可以在源代码管理中维护代码。我们一直使用 SQL 脚本来完成。 无论您是从应用程序还是从其他地方访问数据库,这都会起作用。 如果您在数据库中使用触发器,您将如何识别进行更改的用户?我想您可以获得数据库登录名(假设每个用户都有一个单独的数据库登录名)但是,对于只有一个数据库用户的基于 Web 或 n 层的应用程序呢?您是否会在每个表中添加一个 updated_by 字段并将其存储为更改后的值之一?

以上是关于LinqToSQL 和审计更改的字段的主要内容,如果未能解决你的问题,请参考以下文章

使用新的架构更改更新 LinqtoSql 数据库?

即使 JPA 实体不脏,我是不是可以强制 spring-data 更新可审计字段?

在 LinqToSql 中,如何对实体的自定义属性启用更改跟踪?

从LINQ开始之LINQ to Objects(上)

如何在数据库中保留修改的历史细节(审计跟踪)?

有效的审计方式