如何在现实世界的项目中使用数据库触发器?

时间:2011-06-25 16:29:41

标签: sql entity-framework triggers

我已经在最后的弱点中学到了很多关于触发器和活动数据库的知识,但我对这些实际例子有一些疑问。

在工作中,我们将实体框架与ASP.Net和MSSQL Server一起使用。我们只使用自动生成的约束而没有触发器。

当我听到触发器时,我问自己以下问题:

  1. 触发器可以执行哪些任务? 例如:报告数据的生成:目前报告的数据是用vb创建的,但我认为触发器也可以处理这个问题。 vb中的创建需要花费大量时间,用户不需要等待它,因为它不需要他的工作。 这是一个触发器完美任务的例子吗?

  2. OR-Mapper如何处理触发操纵数据? 例如:OR-Mapper是否识别触发器是否操纵数据?实体框架似乎缓存了大量数据,因此在处理框架中的插入/更新/删除之后,如果触发器操纵数据,我不确定它是否读取更新的数据。

  3. 数据库中应该有多少约束处理? 例如:有时数据库中的约束似乎比上面的层(vb.net,...)更容易和更快,但是如何向OR-Mapper处理的上层抛出异常? 在任何OR-Mapper中处理SQL异常(来自触发器)是否有一个很好的解决方案?

  4. 提前致谢

4 个答案:

答案 0 :(得分:3)

当您听说新工具或胎儿时,并不意味着您必须在任何地方使用它。您应该考虑应用程序的设计。

当逻辑在数据库中时,触发器会被大量使用,但如果在数据库之上构建ORM层,则需要使用ORM在业务层中使用逻辑。这并不意味着你不应该使用触发器。这意味着您应该以与存储过程或数据库函数相同的方式将它们与ORM一起使用 - 只有在它有意义或何时提高性能时才使用它们。如果您将大量逻辑传递给数据库,您可以丢弃ORM,也许整个业务层,并使用两个分层架构,UI将直接与数据库对话,这将完成您所需的一切 - 这种架构被认为是“旧的”。

  1. 使用ORM触发器对某些数据库生成的数据(如审计列或主键值的自定义序列)很有帮助。
  2. 当前的ORM主要不喜欢触发器 - 它们只能对当前处理的记录的更改作出反应,例如,如果您保存订单记录并且更新触发器将修改所有订购的项目,则没有自动方式让ORM知道 - 您必须手动重新加载数据。在EF中,所有在数据库中修改或生成的数据都必须使用StoreGeneratedPattern.IdentityStoreGeneratedPattern.Computed进行设置 - EF完全遵循模式,其中逻辑位于数据库或应用程序中。一旦定义了在数据库中分配的值,就无法在应用程序中更改它(它将不会持久存在)。
  3. 只有在验证通过时,您的应用程序逻辑才应负责数据验证和调用持久性。如果您事先知道事务将失败,则应避免不必要的事务和数据库往返。

答案 1 :(得分:1)

我将触发器用于两个主要目的:审核和更新修改/插入时间。审计时,触发器将数据推送到相关的审计表。这不会以任何方式影响ORM,因为这些表通常不会映射到主数据上下文中(在需要查看审计数据时会使用单独的审计数据上下文)。

在记录/修改插入/修改时间时,我通常会将模型中的这些属性标记为[DatabaseGenerated( DatabaseGenerationOptions.Computed )]这可以防止数据层中设置的任何值被持久化回DB并允许触发器强制设置DateTime字段正确。

我以这种方式管理审计和这些日期并不是一条硬性规则。有时我需要比数据库本身更多的审计信息,而是在数据层中处理审计。有时我想强制应用程序更新日期/时间(因为它们可能需要在同时更新的多个行/表中相同)。在这些情况下,我可能会使字段为空,但模型中的[Required]会强制在模型可以保留之前设置日期/时间。

答案 2 :(得分:0)

旧的Infomodeler / Visiomodeler ORM(不是您所想的 - 它是对象角色建模)在生成物理模型时提供了另一种选择。它将通过触发器提供所有参照完整性。有两个原因:

  1. 有些dbmses(特别是Sybase / SQL Server)还没有声明性的RI,而且
  2. 它可以提供更细粒度的完整性 - 例如“不超过两个孩子”或“儿子或女儿,但不是两者”或“强制性儿子或女儿,但不是两者兼而有之。”
  3. 因此,以与任何RI约束相同的方式触发与模型相关的逻辑。在SQL Server中,它使用RAISERROR处理违规行为。

    触发器的一个概念性问题是它们本质上是无上下文的 - 它们总是在不管上下文的情况下触发(至少没有太大的痛苦,你可能最好将其逻辑与其他特定于上下文的逻辑包括在一起。)所以全局域约束是我发现它们有用的唯一地方 - 我想这是识别“参照完整性”的另一种通用方法。

答案 3 :(得分:0)

触发器用于维护数据的完整性一致性(通过使用约束),帮助数据库设计人员确保完成某些操作并创建数据库更改日志

例如,在给定数字输入的情况下,如果希望将该值限制为小于100,则可以编写一个触发器,该触发器将在更新或插入时为每一行触发,如果该触发器的值引起应用程序错误列不符合该约束条件。

假设您要将历史更改记录到表中。您可以创建一个触发器,每个 INSERT UPDATE DELETE 分别触发 AFTER 日志表。如果您需要执行自定义的自定义逻辑,那么触发器可能会吸引您。

相关问题