Ошибка при вставке в таблицу вместо триггера из структуры данных объекта

Я использую Entity Framework 4, при вставке новой записи с использованием Entity Framework в таблицу, которая имеет вместо триггера вставки, в то время как таблица имеет столбец идентификаторов, вместо триггера используется для изменения одного из вставленных значений в соответствии с определенной логикой,Entity Framework вызывает исключение "Оператор Store update, insert или delete затронул неожиданное количество строк (0). Возможно, объекты были изменены или удалены с момента загрузки объектов. Обновить записи ObjectStateManager".

Может ли кто-нибудь помочь, как обойти это исключение?

4 ответа

Используя Entity Framework 4.1, решение, опубликованное Ladislav для добавления Select of Scope_Identity() в конец тела триггера, решило проблему для меня. Я скопировал все создание триггера здесь для полноты. С помощью этого триггера я смог добавить строки в таблицу, используя 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

Изменить для обработки вычисленных значений (спасибо Крису Моргану в комментариях):

Если у вас есть другие вычисленные значения в таблице, вам нужно будет включить их и в SELECT. Например, если у вас был CreatedDate столбец, который использует GETDATE() Вы бы сделали выбор следующим образом:

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

Вместо триггера выполняется операция вставки, созданная структурой Entity. Это может быть потенциальной проблемой, потому что после того, как вы используете столбец идентификации, за каждой вставкой следует:

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

Таким образом, вопрос в том, что происходит с этим запросом после замены вставки. Если он выполняется и возвращает ноль, вы получаете исключение. Вы можете добавить его после того, как вставите запись в свой триггер, но это не поможет, если исходный запрос также будет выполнен.

Вы можете изменить свой триггер до или после вставки и изменения данных.

Вам также необходимо вернуть любые свойства, помеченные как вычисленные

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

Я также обнаружил, что для StoreGeneratedPattern необходимо установить значение Identity, чтобы оно работало со столбцом nvarchar, который я использовал в качестве первичного ключа, но который не генерировал значение идентификатора. Это было для ситуаций триггера после вставки, который вычислял уникальное значение для хранения в ключевом столбце. В других ситуациях (добавление и обновление) может потребоваться установить значение Computed.

Другие вопросы по тегам