Linq-to-sql在触发器附加时插入和更新失败

11

最近我在使用linq-to-sql时遇到了一些问题。问题是如果我们在事件上附加了触发器,它会“认为”在插入和更新时失败。例如,当更改行时附加了一个触发器来将“LastUpdated”列设置为当前时间。这会导致linq-to-sql认为更新或插入失败,但这只有在某些情况下才会发生。我的猜测是,这可能发生在SQL服务器负载过重时,因此无法在进行验证之前执行触发器。由于我的脚本只是整个脚本的一部分,因此禁用触发器不是一个选项,所以我需要找到解决方案,或者重写我的程序。

触发器。

USE [cnhha]
GO
/****** Object:  Trigger [dbo].[LastUpdated]    Script Date: 05/12/2011 16:26:51 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER TRIGGER [dbo].[LastUpdated] ON [dbo].[CN_User] 
FOR INSERT, UPDATE
AS

update cn_user set lastupdated=getdate() where campusnetuserid in (select campusnetuserid from inserted)

您可能需要在测试环境中禁用触发器以验证是否确实存在问题。是否可以从LINQ2SQL语句中删除触发器修改的字段,以便它不会尝试进行验证? - n8wrl
触发器的类型是什么?更新前还是更新后? - Sam Saffron
请问您能否添加触发器的外观是什么样子? - DForck42
是的,我们已经尝试过移除触发器,然后一切都运行得非常完美!触发器在更新之后运行,并将“LastUpdated”列更新为当前日期,在触发触发器的行上。 - Androme
从我之前的阅读中,我得出结论,Linq-SQL中的触发器是不可行的。我可能错了,但我使用它们只会带来麻烦。 - Hux
你能描述一下你所采用的验证方式吗?它具体是如何失败的? - arcain
4个回答

8
您在触发器中可能需要使用SET NOCOUNT ON,除了我在“SET NOCOUNT ON usage”问题中提到的狭窄情况(SQLDataAdapter)之外,大多数客户端代码都需要使用它。
如果您能够更改客户端UPDATE以使用DEFAULT关键字,则也可以删除触发器。
update cn_user
set col1 = this, col2 = that,...,
    lastupdated= DEFAULT
where ...

2
你的触发器是否通过SELECT语句返回任何数据?请参阅此MSDN文章:CREATE TRIGGER

当触发器触发时,结果会像存储过程一样返回给调用应用程序。为了消除由于触发器触发而将结果返回到应用程序的情况,请不要在触发器中包含返回结果的SELECT语句或执行变量赋值的语句。包含返回结果给用户的SELECT语句或执行变量赋值的语句的触发器需要特殊处理;这些返回结果必须写入允许修改触发器表的每个应用程序中。如果必须在触发器中进行变量赋值,请在触发器开头使用SET NOCOUNT语句来消除任何结果集的返回。

另外,如果你认为触发器对数据库引擎造成了沉重负担,你考虑使用Service Broker使它们的后处理异步吗?

如果您能包含一个代表性触发器的代码,那么我们可以进一步诊断您遇到的问题。


触发器没有选择,也不返回任何数据。我已经在我的第一篇文章中添加了相关的触发器代码! - Androme

0

你可以使用SQL Profiler来帮助你监控整个过程中发生的所有活动。你可以捕获并保存每个事件的数据到文件或表中。


我们尝试使用SQL分析器,所有由linq-to-sql发送到数据库的命令都没有问题。只是linq-to-sql本身认为它失败了。 - Androme

0
如果触发器在您的代码背后更新属性值会干扰您的自定义实体验证逻辑,那么您可以完全避免触发器并直接设置实体上的LastUpdated属性,或者不对LastUpdated属性的值执行任何验证(除了模式验证)吗?


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