EF 4.1代码优先向表添加触发器

17

如何在使用 EF 4.1 的 Code-First 方法创建的表中添加触发器最佳方案是什么?

我正在考虑的方法是在 OnModelCreating 或 Db 上下文初始化时执行自定义 SQL 查询。

是否有更好的想法?

2个回答

23
使用自定义初始化器是唯一的选项,如果你想让EF为你创建触发器并执行"CREATE TRIGGER" SQL命令(类似此处的代码)。还要记得在触发器代码开头加上"SET NOCOUNT ON"。
但是,与触发器逻辑相关的问题更加复杂。如果你想要一个能够修改传递给数据库数据的触发器,你必须明白,触发器所做的更改不会反映在你当前的上下文中。上下文仍然只知道带有你传递到数据库的数据的实体。通常可以通过将由触发器修改的属性设置为DatabaseGeneratedOption.Computed(用于更新)或DatabaseGeneratedOption.Identity(用于插入)来解决这个问题。在这种情况下,你不能在应用程序中修改属性,它们必须在数据库中进行修改。EF将确保在修改后选择这些属性并传递给实体。问题是这在Code First中无法工作

在我的当前情况下,我需要更新其中一个表格中的“DateModified”列。 “DateModified”的值不会被当前上下文使用。 - Dmitri
实际上思考一下,由于POCO对象被上下文跟踪,我能利用它来更新我的时间戳吗? - Dmitri
“DateModified”不会被上下文使用,这与代码优先方法不符,其中您仅定义上下文使用的列。 - Ladislav Mrnka
在保存更改之前,您当然可以在上下文中更改DateModified,通过覆盖SaveChanges迭代所有修改的实体并设置字段。 - Ladislav Mrnka
“DateModified”将被使用,但不在当前上下文中。感谢所有信息! - Dmitri

1
我不太确定你的意思。如果你想在表上创建一个实际的SQL触发器,那么我会像平常一样在SQL中创建触发器。如果你的意思是每当你的实体集合被修改时,你想要在代码中进行某种处理/更新,那么我认为你需要编写一个自定义方法,在该实体集合被更新时调用该方法。

2
我确实需要在表上设置一个实际的触发器。如果我直接在SQL中创建它,它将会因为“DropCreateDatabaseIfModelChanges”而丢失。 - Dmitri
如果需要一个SQL触发器,您可以创建一个脚本,并在重新创建表时运行它。但那有点恶心。Ladislav提出了一个很好的观点-每次触发器运行时,您都需要刷新上下文。如果可以在代码中完成,我认为您会节省一些麻烦。 - AllenG
2
这根本没有任何意义...为什么不利用SQL而不是从代码中进行二次调用?这样可以减少编写和执行的代码量,同时使SQL执行其应该执行的操作,即触发器。更不用说,这还可以减少一次对数据库的调用。 - IyaTaisho

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接