【问题标题】:Is EF or SQL the better choice to audit data changes?EF 或 SQL 是审计数据更改的更好选择吗?
【发布时间】:2011-11-17 05:17:15
【问题描述】:

要求似乎很简单:当数据更改时,审核更改。

以下是方程式的一些重要部分:

  1. 我的应用程序中的数据跨越多个表(一些交叉引用表)。
  2. 我的 DTO 很深,有条件地填充了导航属性。
  3. 加载后,我复制原始 DTO 及其“原始值”。
  4. 请求保存时,原始 DTO 包含更改。
  5. 理想情况下,外键读起来像有用的文本而不是 ID 号。

与 TFS 的酷历史功能不同,我的似乎更复杂,因为有许多相关的表和条件子实体。

我看到了三种可能性(到目前为止):

  1. 我可以使用 C# 来反映对象并创建前后记录。
  2. 我可以使用 SQL 2008R2 中的触发器来捕获更改并合并之前/之后的记录。
  3. 我可以存储原始的 before/after 对象并让 SQL 2008R2 解析它们。

请注意:现在,在我看来,SQL 2008R2 的 CDC 选项过于繁重。我真的在寻找可以构建的东西,但我承认我现在对任何事情都持开放态度。

我的问题

在我开始构建这个之前: 其他人如何处理审计复杂的 EF DTO?

是否有可用的低(ish)技术解决方案?

提前谢谢你。

StackOverflow 上已有相关但不完全相关的问题:Implementing Audit Log / Change History with MVC & Entity FrameworkCreate Data Audit in SQL Serverhttps://stackoverflow.com/questions/5773419/how-to-audit-many-to-many-relationship-in-entity-frameworkMaintaining audit log for entities split across multiple tablesLinq to SQL Audit Trail / Audit Log: should I use triggers or doddleaudit? 不提供答案。

【问题讨论】:

  • 不知道您为什么不将 SQL Server 的本机审核功能列为选项。
  • 抱歉@Craig,您对我的 DBA 做出了错误的假设。这完全超出了他们当前的技能范围,并且会给解决方案团队带来一场噩梦(和无休止的延迟),让 IT 部门需要它。这里只是一个现实,这就是我排除它的原因。
  • 好吧,即使他们还不知道,但至少记录在案。

标签: c# sql-server entity-framework audit


【解决方案1】:

如果审计是一个真正的要求,我会选择触发解决方案......因为其他方法有几个“缺点”:

  • 对通过您的应用程序以外的其他方式发生的任何更改“视而不见”
  • 如果您进行了一些代码更改而忘记添加审计代码,那么审计线索就会出现“盲点”

可以保护基于触发器的解决方案,以便只有特殊用户才能看到审计数据...

我通常与 Oracle 合作,但根据我在这种情况下的经验:允许应用程序仅通过 Views 选择权限,任何插入/删除/更新都应通过存储过程完成,审计跟踪应通过触发器完成...

【讨论】:

  • 正确。此外,触发器可以使用 SUSER_SNAME() 来获取登录人员的用户 ID 并对数据行进行更改,而 SQL Server 的内置审计功能却奇怪地无法做到这一点。
  • 不抱歉,@HardCode(和 Yahia),触发器有问题。想象一下交叉引用表另一侧的新数据记录。它是在交易中的交叉记录之前创建的,这意味着触发器无法将插入的记录与父记录相关联 - 审计将是一个孤儿。请记住,在事务中操作很重要,因为已删除的表在范围内。你怎么能解决这个问题?
  • @Jerry Nixon - 如果您的数据模型是相应构建的,您可以很好地关联审计条目......如果需要,您可以随时使用描述的 SP 方法来丰富审计......我们使用以上具有非常复杂的模型,并且从未遇到过您描述的问题(或者我可能只是不明白您的意思是什么?)...
  • 不,@Yahia,这根本不是真的。表上的触发器是不够的。如果你有复杂的关系并且你在同一个事务中更新它们(比如使用 EF),你根本无法有效地完成审计。也许 Oracle 以不同的方式处理事务,但是,不,在 SQL Server 中,触发器解决方案无法将一个表中的更改与相关表中的更改相关联,特别是如果事务包括对树中任何其他表的 Delete 语句。 CDC 可以工作,但不能触发。
【解决方案2】:

我最近在实体框架之上实现了一个审计日志管理器。当我实例化我的审计管理器时,我反映了所有的实体类,并存储了属性信息。然后在对象上下文 SavingChanges 事件中,我审核所有更改。它工作得很好。对于外键,我只是在更改前后存储它们的 ID。

这个解决方案的好处是它不需要任何额外的编码。创建排序日志管理器后,您不必担心添加新触发器或在添加新列时修改触发器。对实体类所做的任何更改都将在反映类时自动获取。

【讨论】:

  • 不抱歉,@Mservidio,EF 有问题。考虑插入没有键的情况。也许父记录有一个键(或者可能没有),也许一些子记录在插入后还没有数据库分配的键。问题是,您正在创建一个不引用记录的审计记录。让我提出第二个问题,即默认值或受触发器影响的值,这种方法完全忽略了这些值。
  • 好点@Jerry-Nixon。大约一个月前我编写了我的实体框架,你说的是真的。在我的情况下,不需要创建新实体的 ID,因此我们可以在创建时不使用它们。修改和删除都有键。但是,您现在让我想到我可以跟踪保存的实体并在保存后、在检索到自动生成的列和计算的列之后进行日志记录,然后记录它。
  • 我现在可以回去重温一下,看看我能不能做到这一点。当然,这种方法的一个缺陷是日志记录会在更改之后发生,因此如果日志记录发生任何问题,它就不能保证日志总是如此。因此,同意如果您需要坚如磐石的审计流程,这不是更好的方法。如果您只需要在初始创建时不需要 Id 的轻型日志记录,那就太好了。待续...如果我在 EF 中保存更改后将 Id 提取到我的审核日志中,我将提供更新。
  • 我们正在尝试使用 DTO 的“保存前”版本和 DTO 的“保存后”版本创建一个解决方案,以从中构建审计记录。这似乎是最有希望的。我们需要的所有数据和密钥都存在于这两个版本中。剩下的难点在于这种改变不是很安全。我们的要求实际上是针对“历史”而不是“审计”,所以我们很好。你可能不是,我不知道。
【解决方案3】:

好吧,让我们看看。 SQL Server auditing 已经存在,附带工具,您的 DBA 可能已经知道,不会减慢您的应用程序,并且可以跟踪 events that the application itself will never even see

另一方面,在 EF 中滚动您自己将允许您审核非 SQL Server 数据源。它也不需要EE。

【讨论】:

    【解决方案4】:

    触发解决方案,优点:

    1. 无法绕过审核

    触发解决方案,缺点:

    1. 无法审核非 SQL 数据
    2. 无法审核插入时的复杂对象

    实体框架,优点:

    1. 可以审核所有内容
    2. 可以审计任何状态的复杂对象

    实体框架,缺点:

    1. 可以绕过(如直接到 SQL)
    2. 需要原始值的副本

    我的选择是实体框架。使用 STE 更容易。

    无论哪种方式,您都必须自己动手。

    【讨论】:

      猜你喜欢
      • 2011-07-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-30
      • 1970-01-01
      • 2012-02-20
      • 1970-01-01
      相关资源
      最近更新 更多