2011-04-28 60 views
27

我正在使用實體框架4,插入一個新的記錄使用實體框架的表中,而不是插入觸發器,而表具有標識列時,而不是觸發器用於根據某種邏輯修改其中一個插入值,實體框架引發異常「存儲更新,插入或刪除語句影響了意外數量的行(0)。實體可能已被修改或刪除,因爲實體是加載。刷新ObjectStateManager條目「。插入表時有錯誤,而不是從實體數據框架觸發

任何人都可以幫助如何解決這個異常?

+1

有沒有原因您沒有標記答案正確?瑞恩格羅斯在下面的答案爲我解決了這個問題。 – 2015-12-01 16:54:08

回答

12

而不是執行觸發器而不是實體框架創建的插入操作。

select [Id] 
from [dbo].[TableXXX] 
where @@ROWCOUNT > 0 and [Id] = scope_identity() 

所以現在的問題是,一旦插入替換什麼與此查詢情況:因爲一旦你使用的標識列每個插入之後這可能是潛在的問題。如果它被執行並返回null,你會得到和異常。你可以在你的觸發器中插入記錄後添加它,但如果原始查詢也被執行,它也無濟於事。

您可以將您的觸發器更改爲插入和修改數據之前或之後。

+0

您能詳細說明嗎?但如果原始查詢也被執行,它也無濟於事。 – Aducci 2014-04-09 20:48:04

52

使用實體框架4.1,Ladislav發佈的解決方案將Select的Scope_Identity()添加到觸發器主體的末尾,爲我解決了這個問題。爲了完整性,我在這裏複製了整個觸發器的創建過程。有了這個觸發器defenition,我可以使用context.SaveChanges()將行添加到表中。

ALTER TRIGGER [dbo].[CalcGeoLoc] 
    ON [dbo].[Address] 
    INSTEAD OF INSERT 
AS 
BEGIN 
-- SET NOCOUNT ON added to prevent extra result sets from 
-- interfering with SELECT statements. 
SET NOCOUNT OFF; 

-- Insert statements for trigger here 
INSERT INTO Address (Street, Street2, City, StateProvince, PostalCode, Latitude, Longitude, GeoLoc, Name) 
SELECT Street, Street2, City, StateProvince, PostalCode, Latitude, Longitude, geography::Point(Latitude, Longitude, 4326), Name 
FROM Inserted; 

select AddressId from [dbo].Address where @@ROWCOUNT > 0 and AddressId = scope_identity(); 
END 

編輯處理的計算值(在評論中感謝Chris摩根):

如果表中的任何其他計算值,你必須包括他們在SELECT也是如此。例如,如果你有一個CreatedDate列使用GETDATE()你會作出選擇是這樣的:

SELECT [AddressId], [CreatedDate] from [dbo].Addresses where @@ROWCOUNT > 0 and AddressId = scope_identity(); 
+1

我加了「SELECT FROM INSERTED;」到觸發器體的末端,它就完成了這個任務。 – muruge 2011-06-20 20:26:33

+7

你真了不起。如果可以的話,我會投票150,000次。 – Jeff 2011-12-02 17:01:44

+4

如果表中還有其他任何計算值,您也必須將它們包含在SELECT中。例如,如果你有一個使用GETDATE()的CreatedDate列,你可以這樣選擇:SELECT [AddressId],[CreatedDate] from [dbo] .Addresses where @@ ROWCOUNT> 0 and AddressId = scope_identity();' – 2014-02-08 04:02:14

2

您還需要返回任何屬性標記爲已計算

select [Id], [YourComputedColumn] 
from [dbo].[TableXXX] 
where @@ROWCOUNT > 0 and [Id] = scope_identity() 
0

我也發現你需要將StoreGeneratedPattern設置爲Identity以使其在我用作主鍵但不生成標識值的nvarchar列上工作。這是針對後插入觸發器的情況,該觸發器計算了存儲在鍵列中的唯一值。在其他情況下(添加和更新),可能需要將其設置爲計算。