Ошибка при вставке в таблицу вместо триггера из структуры данных сущности
Я использую сущность 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.