而不是插入触发器会导致实体框架的保存更改中出错


这是我

的第一篇文章,但我经常来这里为我的问题找到正确的解决方案。

我有一个数据库(SQL Server 2008 R2(,其中包含一个表,该表具有用于检查插入数据的INSTEAD OF INSERT触发器。

如果是重复的行,请更新该行

;否则,请插入该行。

触发:

ALTER TRIGGER [dbo].[CheckDataTrigger]
    ON [dbo].[MonitorSummary]
    INSTEAD OF INSERT
AS 
BEGIN
    SET NOCOUNT OFF
    IF exists( select * from inserted i, MonitorSummary ms
            where ms.ServiceUrl = i.ServiceUrl
                AND ms.AppName = i.AppName
                AND ms.BuildVersion = i.BuildVersion
                AND ms.FunctionName = i.FunctionName
                AND ms.Company = i.Company
                AND ms.UserName = i.UserName
                AND ms.ServerName = i.ServerName)
    BEGIN
       UPDATE MonitorSummary  
       SET MonitorSummary.Function_Count = inserted.Function_Count,
           MonitorSummary.Execution_Time_Sum = inserted.Execution_Time_Sum,
           MonitorSummary.LogLevel = inserted.LogLevel
       FROM inserted
       WHERE MonitorSummary.ServiceUrl = inserted.ServiceUrl
       AND MonitorSummary.AppName = inserted.AppName
       AND MonitorSummary.BuildVersion = inserted.BuildVersion
       AND MonitorSummary.FunctionName = inserted.FunctionName
       AND MonitorSummary.Company = inserted.Company
       AND MonitorSummary.UserName = inserted.UserName
       AND MonitorSummary.ServerName = inserted.ServerName
    END
    ELSE
    BEGIN
      INSERT INTO MonitorSummary
         SELECT 
             i.ServiceUrl, i.EmailAdress, i.EmailSent, i.AppName, i.BuildVersion, 
             i.FunctionName, i.Company, i.UserName, i.ServerName, i.Function_Count, 
             i.Execution_Time_Sum, i.LogLevel
         FROM inserted i
    END
    SELECT Monitor_Id 
    FROM MonitorSummary 
    WHERE @@ROWCOUNT > 0 AND Monitor_Id = SCOPE_IDENTITY()
END

如您所见,SET NOCOUNT OFF和我在触发器结束时执行选择查询。有关该表的额外信息:

CREATE TABLE [dbo].[MonitorSummary](
    [Monitor_Id] [int] IDENTITY(1,1) NOT NULL,
    [ServiceUrl] [nvarchar](100) NULL,
    [EmailAdress] [nvarchar](100) NULL,
    [EmailSent] [bit] NOT NULL default 0,
    [AppName] [nvarchar](100) NULL,
    [BuildVersion] [nvarchar](100) NULL,
    [FunctionName] [nvarchar](100) NULL,
    [Company] [nvarchar](100) NULL,
    [UserName] [nvarchar](100) NULL,
    [ServerName] [nvarchar](100) NULL,
    [Function_Count] [int] NOT NULL default 0,
    [Execution_Time_Sum] [numeric](18, 8) NOT NULL default 0,
    [LogLevel] [nvarchar](50) NULL,
PRIMARY KEY CLUSTERED 
(
    [Monitor_Id] ASC
)

我在使用之前已经测试了触发器。 效果很好!

测试代码:

INSERT INTO MonitorSummary VALUES
    ('ServiceUrl2', 'EmailAdress2', 0, 'AppName2', 'BuildVersion2', 'FunctionName2',
        'Company2', 'UserName2', 'ServerName2', 1, 1, 'LogLevel2'),
    ('ServiceUrl2', 'EmailAdress2', 0, 'AppName2', 'BuildVersion2', 'FunctionName2',
        'Company3', 'UserName2', 'ServerName2', 1, 1, 'LogLevel2'),                 
    ('ServiceUrl3', 'EmailAdress3', 0, 'AppName2', 'BuildVersion2', 'FunctionName2',
        'Company2', 'UserName2', 'ServerName2', 1, 1, 'LogLevel2'),
    ('ServiceUrl3', 'EmailAdress3', 0, 'AppName2', 'BuildVersion2', 'FunctionName2',
        'Company2', 'UserName2', 'ServerName2', 2, 2, 'LogLevel2')

现在,问题是EF(实体框架(不起作用。

我认为这在 Web 服务 (.asmx( 中工作无关紧要,因为我使用测试表(没有触发器(测试 EF,一切正常。

在此代码中,我向 EF 添加了一些对象并保存更改。

已经尝试保存循环中的更改,但这没有效果......

private void StoreData(MonitorSummary[] data)
{
    foreach (MonitorSummary item in data)
    {
        MonitorEntity.MonitorSummary.AddObject(item);
        //MonitorEntity.SaveChanges();
    }
    MonitorEntity.SaveChanges();
}

我总是以这个错误结尾:

存储更新、插入或删除语句影响了意外的行数 (0(。此后,实体可能已被修改或删除 实体已加载。刷新对象状态管理器条目。

我还尝试Attach对象并将并发模式更改为固定,所有这些都不起作用。

我什至尝试了一个AFTER INSERT触发器,但这不是我想要的解决方案,我必须编写更多代码,因为它已经插入到表中。

现在有人可以解决我的问题吗?

我相信您需要在触发器的 UPDATE 部分中设置@@identity。为此,请创建一个简单的插入查询并执行它。假设监视器摘要中有标识列id

declare @strSql varchar(1000)
declare @id int
select @id = max (id) 
  from MonitorSummary
 where -- whole join condition to identify changed record(s)
set @strSql = 'SELECT Identity (Int, ' + Cast(@id As Varchar(10)) + ',1) AS id 
                     INTO #Tmp'
EXECUTE (@strSql)

如果使用 Sql Server 2005 或更高版本,则 UPDATE 中有一个输出子句,可用于检索已更改记录的列表。

顺便说一句,您可以删除存在部分并检查 UPDATE 是否将@@rowcount设置为零; 如果是,则需要插入行。

相关内容

  • 没有找到相关文章

最新更新