При вставке триггерных разрывов EF Добавить - PullRequest
1 голос
/ 08 мая 2019

Я добавил триггер таблицы SQL Server ON INSERT, и он сломал код вставки Entity Framework моего API. Выдает ошибку:

InnerException = "Оператор хранения, вставки или удаления затронул неожиданное количество строк (0). Возможно, объекты были изменены или удалены с момента загрузки объектов.

Я попытался установить EntityState.Added; Бен здесь , но это не сработало.

Я попробовал предложение от чамара здесь .

Добавлен следующий триггер SQL Server:

ALTER TRIGGER [dbo].[tr_TargetUserDel] 
ON [dbo].[TargetUser]
AFTER  INSERT
AS
BEGIN
    DECLARE @UserId AS INT
    DECLARE @TargetId AS INT
    DECLARE @TargetUserId AS INT

    SELECT @UserId = i.[UserId], @TargetId = i.[TargetId] 
    FROM inserted i

    INSERT INTO [dbo].[TargetUser] ([UserId], [TargetId])
    VALUES (@UserId, @TargetId)

    SELECT @TargetUserId = CAST(@@Identity AS INTEGER)

    DELETE [dbo].[TargetUser] 
    WHERE TargetUserId <> @TargetUserId 
      AND TargetId = @TargetId
END

Это привело к ошибке следующей вставки EF:

targetuser.UserId = interfaceUser.UserId;
targetuser.TargetId = interfaceUserDTO.TargetId;

db.InterfaceTargetUsers.Add(targetuser);                    
db.SaveChanges();      // <<Error thrown

целевой объект модели:

[Table("TargetUser")]
public partial class InterfaceTargetUser
{
    [Key]
    [Column(Order = 0)]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int TargetUserId { get; set; }
    public int UserId { get; set; }
    public int TargetId { get; set; }
}

EF испытывает проблемы со вставкой, но если я запускаю вставку непосредственно в SQL Server, она работает нормально:

INSERT INTO targetuser (TargetId, UserId) 
VALUES (5276, 572)

Изменение триггера в соответствии с chamara здесь работает, но я ищу решение EF.

chamara Обходной путь - добавить это в конец триггера:

SELECT * FROM deleted UNION ALL
SELECT * FROM inserted;

Это работает , но у него нет голосов. Почему это работает? Похоже, должно быть решение EF?

1 Ответ

3 голосов
/ 08 мая 2019

У вас там много проблем:

select  @UserId = i.[UserId], @TargetId=i.[TargetId] from inserted i

Будет работать только тогда, когда псевдо INSERTED имеет только 1 строку.

Также для линии

SELECT @TargetUserId =CAST(@@Identity AS INTEGER)

Будет возвращать только последнее сгенерированное значение идентификатора, а не все.

Измените свой триггер, чтобы он был похож на

ALTER TRIGGER [dbo].[tr_TargetUserDel] ON [dbo].[TargetUser]
AFTER  INSERT
AS
BEGIN
  SET NOCOUNT ON;       
  INSERT INTO [dbo].[TargetUser]([UserId], [TargetId])
  SELECT UserId,
         TargetId
  FROM INSERTED;

  DELETE T
  FROM [dbo].[TargetUser] T INNER JOIN INSERTED TT
  ON T.TargetId = TT.TargetId 
     AND
     T.TargetUserId <> TT.TargetUserId;
  SET NOCOUNT OFF; 
END
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...