gpt4 book ai didi

entity-framework - OptimisticConcurrencyException-SQL 2008 R2而不是使用 Entity Framework 的插入触发器

转载 作者:行者123 更新时间:2023-12-04 06:50:24 27 4
gpt4 key购买 nike

使用SQL 2008 R2 11月发行版数据库和.net 4.0 Beta 2 Azure辅助角色应用程序。辅助角色收集数据并将其插入具有一个标识列的单个SQL表中。由于可能会运行该辅助角色的多个实例,因此我在SQL表上创建了一个Insert Of Of触发器。触发器使用SQL Merge功能执行Upsert功能。使用T-SQL,我能够正确地验证插入而不是触发器功能,在更新现有行的同时插入新行。
这是我的触发器的代码:

Create Trigger [dbo].[trgInsteadOfInsert] on [dbo].[Cars] Instead of Insert
as
begin
set nocount On

merge into Cars as Target
using inserted as Source
on Target.id=Source.id AND target.Manufactureid=source.Manufactureid
when matched then
update set Target.Model=Source.Model,
Target.NumDoors = Source.NumDoors,
Target.Description = Source.Description,
Target.LastUpdateTime = Source.LastUpdateTime,
Target.EngineSize = Source.EngineSize
when not matched then
INSERT ([Manufactureid]
,[Model]
,[NumDoors]
,[Description]
,[ID]
,[LastUpdateTime]
,[EngineSize])
VALUES
(Source.Manufactureid,
Source.Model,
Source.NumDoors,
Source.Description,
Source.ID,
Source.LastUpdateTime,
Source.EngineSize);
End

在worker角色中,我正在使用Entity Framework创建对象模型。当我调用SaveChanges方法时,我收到以下异常:
OptimisticConcurrencyException
Store update, insert, or delete statement affected an unexpected number of rows (0). Entities may have been modified or deleted since entities were loaded. Refresh ObjectStateManager entries.

我知道这很可能是由于SQL不会为每个新插入/更新的行报告一个IdentityScope。然后,EF认为未插入行,并且最终未落实事务。

处理此异常的最佳方法是什么?也许使用SQL合并功能中的OUTPUT?

谢谢!
保罗

最佳答案

正如您所怀疑的那样,问题在于,在具有“身份”列的表中进行的任何插入都会紧随其后的是选择scope_identity(),以填充 Entity Framework 中的关联值。代替触发器将导致错过此第二步,从而导致0行插入错误。

我在this StackOverflow thread中找到了一个答案,建议在触发器的末尾添加以下行(如果项不匹配并且执行了插入)。

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

我使用Entity Framework 4.1进行了测试,它为我解决了这个问题。为了完整起见,我将整个触发器创建都复制到了这里。通过这种触发机制,我可以通过将Address实体添加到上下文中并使用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

关于entity-framework - OptimisticConcurrencyException-SQL 2008 R2而不是使用 Entity Framework 的插入触发器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1806828/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com