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

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

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

Ответ 1

Используя 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();

Ответ 2

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

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

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

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

Ответ 3

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

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

Ответ 4

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