2011-06-25 42 views
1

我学到了很多关于最后弱点中的触发器和活动数据库的知识,但是我有一些关于这些实例的问题。如何在真实世界的项目中使用数据库触发器?

在工作中,我们使用实体框架与ASP.Net和MSSQL服务器。我们只使用自动生成的约束并且不使用触发器。

当我heared有关触发器我问自己以下问题:

  1. 哪些任务可以由触发器执行? 例如:生成报告数据:目前报告的数据是在vb中创建的,但我认为触发器也可以处理这个。 vb中的创建需要很多时间,用户不需要等待,因为这对他的工作没有必要。 这是触发器完美任务的例子吗?

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

  3. 数据库中应该有多少约束处理? 例如:有时数据库中的约束看起来比上图(vb.net,...)更容易和更快,但是如何将异常引发到可由OR-Mapper处理的上层? 是否有任何OR-Mapper中的handeling SQL异常(来自触发器)的良好解决方案?

预先感谢

回答

3

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

当逻辑位于数据库中时触发器被使用了很多,但如果您在数据库顶部创建ORM层,则需要使用ORM在业务层中创建逻辑。这并不意味着你不应该使用触发器。这意味着您应该像存储过程或数据库函数一样将它们与ORM一起使用 - 只有当它有意义或提高性能时。如果你将大量的逻辑传递给数据库,你可以抛弃ORM,甚至整个业务层,并使用两个分层架构,在这个架构中,UI将直接与数据库进行交流,这将完成你所需要的一切 - 这种架构被认为是“旧”的。

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

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

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

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

0

旧的Infomodeler/Visiomodeler ORM(不是你认为的 - 它是对象角色建模)在生成物理模型时提供了一种替代方案。它将提供触发器的所有参照完整性。原因有二:

  1. 一些的DBMS(特别的Sybase/SQL服务器)并没有声明RI着呢,
  2. 它可以提供更细粒度的完整性 - 例如“不超过两个孩子”或“儿子或女儿但不是两者”或“强制儿子或女儿但不是两者”。

因此以与RI约束相同的方式触发与模型相关的逻辑。在SQL Server中,它处理RAISERROR的违规行为。

触发器的一个概念性问题是,它们基本上无上下文 - 它们总是在不考虑上下文的​​情况下触发(至少没有很大的痛苦,并且您可能更好地将其逻辑与其他上下文特定的逻辑包含在一起)。全局域约束是我发现它们唯一有用的地方 - 我想这是识别“参照完整性”的另一种通用方法。

+0

自从SQL Server/Sybase何时没有DRI最后? 90年代初? – gbn