ошибка при вставке в таблицу вместо триггера из структуры данных объекта - PullRequest
27 голосов
/ 28 апреля 2011

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

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

Ответы [ 4 ]

56 голосов
/ 10 июня 2011

Используя 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();
14 голосов
/ 29 апреля 2011

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

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

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

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

2 голосов
/ 10 апреля 2014

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

select [Id], [YourComputedColumn]
from [dbo].[TableXXX]
where @@ROWCOUNT > 0 and [Id] = scope_identity()
0 голосов
/ 21 апреля 2015

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...