使用带有 MVC4 SQL Server 的实体框架插入后触发器不会触发

Posted

技术标签:

【中文标题】使用带有 MVC4 SQL Server 的实体框架插入后触发器不会触发【英文标题】:Trigger does not fire after insert using Entity Framework with MVC4 SQL Server 【发布时间】:2013-09-22 16:44:18 【问题描述】:

我有以下问题。

我使用触发器为我的网站进行统计。

在我的控制器中,我使用以下代码:

 db.MyModel.Add(model);
 db.SaveChanges();

当我在 SQL Server Management Studio 中插入记录时,我的触发器运行良好。但是当我从网站插入记录时,我的触发器不会触发。

我在其他桌子上有类似的触发器,它们都运行良好。我不知道为什么只有这张表会导致问题。我还尝试删除 edmx 文件并再次创建它,但仍然没有运气。 我需要做些什么才能使其正常工作吗?

我正在使用 Entity Framework 5、MVC4、Visual Studio 2012、MSSQL Server 2008 R2。

谢谢。

更新#1: 从网站插入记录时,新记录会保存到数据库中,但不会发生触发。程序不会产生任何错误。

【问题讨论】:

Entity Framework 没有任何魔法可以让它绕过触发器。尝试运行 SQL Profiler 以查看哪些命令正在访问数据库。 从 Profiler 查看 SQL 跟踪的结果会很有帮助。查看触发器本身的内容也将有所帮助。 我没有对 Profiler 做任何研究。所以请稍等。如果我仍然找不到问题,我需要谷歌并发布 SQL Trace 的结果。谢谢大家:) 【参考方案1】:

如果在 SQL Server 中出现 UPDATEINSERT INTO 语句,触发器将触发。除非您在db.SaveChanges(); 之前实际更改了一些数据,否则您的代码不会直接执行更新。

唯一的另一种可能性是触发器在 DML 操作之前被禁用,然后再启用。

【讨论】:

可能是我的信息不是很清楚。 “db.MyModel.Add(model);”中的模型是从 Web 表单创建的新实体。新记录成功插入数据库。这意味着 INSERT INTO 语句已经发生,对吧?对不起,我是新手 :( 您的触发器配置不正确,或者您没有将记录插入表中。您可以使用 SQL Server Management Studio 查看使用SELECT * FROM [TableInQuestion] 的记录以查看您使用 Web 应用插入的记录吗? 是的,记录已插入。但是扳机还是不能开火。我还尝试在该表上创建新触发器,但在通过 Web 应用程序插入后它仍然不会触发。 (直接插入数据库仍然有效)。 UPDATE 后的另一个触发器仍然可以在 Web 应用上运行。 使用触发代码更新您的问题,并使用 Profiler 抓取 Entity Framework 生成的代码。触发器不是可选的,没有办法阻止触发器运行 -> 触发器写入不正确,或者没有插入数据。【参考方案2】:

我在使用带有 SQL Server 数据库的实体框架时遇到了同样的问题。

要在数据库上触发触发器,您需要在“db.SaveChanges();”之后使用“TransactionScope”发送“提交”命令。

我正在使用 Entity Framework Core 库。 这是一个例子:


using (var ts = new TransactionScope())

    using (var db = new DbContext()) // Modify to you Context Class
    
        // Your logic code
            
        db.MyModel.Add(model);
        db.SaveChanges();
        
        // commit
        ts.Complete();
    

【讨论】:

我认为这是使用事务范围时的预期行为。根据触发器的设置方式,在事务提交之前它真的不能触发。【参考方案3】:

EF 使用sp_executesql('query_string') 语句进行查询。在这种情况下不会触发触发器。

编辑: @Gert Arnold - 是的,您的评论是对的。我粘贴了错误的链接,但找不到正确的链接了。公平地说,我已经删除了链接,但我的回答是正确的。即使在 SSMS 中使用 sp_executesql('query_string') 也不会触发表上的触发器。解决方法是创建一个包含所需操作的存储过程,并像这样从 EF 调用它:

dbContext.Database.SqlQuery<YourModel>("StoredProcedureName",params);

触发器将按预期触发。

【讨论】:

错了!该链接没有说明功能,而是说明错误。 在我在sp_executesql +“没有触发触发器”上找到的每一次点击中,导致错误的总是错误的(或完全愚蠢的)触发器代码。 sp_executesql 不会触发触发器的可能性很小(我敢说不可能)。唯一接近的是here,但这是一个不同的问题。 @Gert Arnold 如果触发器在 SSMS 中的标准查询中被触发且没有错误,那么它的代码是可以的......但是如果您找到任何解决方案或未触发它的原因,请在此处发表评论- 我很乐意学习新东西。

以上是关于使用带有 MVC4 SQL Server 的实体框架插入后触发器不会触发的主要内容,如果未能解决你的问题,请参考以下文章

实体框架探查器 - 带有 EF 6 的 ASP.NET MVC4 - 无法确定提供程序名称

使用带有实体框架代码优先和 ASP.NET MVC 3 和 mvc miniprofiler 的 SQL Server CE 时出现问题

带有 LinqToSql System.Data.Linq.DuplicateKeyException 的 C# 和 SQL Server 数据库出错:无法使用已在使用的键添加实体。

为啥 Asp.net MVC4 不能使用 SQL Server Session 状态存储的 cookieless

如何使用 C# 代码部分中的 SQL 函数使用 MVC 4 中的实体框架

带有实体框架和 SQL Server 数据库的 ASP.NET MVC - 图像未显示在视图中......错误显示“无法将“字节”转换为“字符串”