0

У меня есть класс CF:EF CF 4.2 и SQL Вместо вставки триггера

public class A 
{ 
    [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)] 
    public int Id {get;set;} 
    [Required] 
    public string Name {get;set;} 
    public string LoweredName {get;set;} 
    [Timestamp] 
    public byte[] RowVersion {get;set;} 
} 

В базе данных у меня есть триггер:

CREATE TRIGGER IOI_LoweredName 
    ON Abc 
    INSTEAD OF INSERT 
AS; 
BEGIN; 
    SET NOCOUNT ON; 

    INSERT INTO Abc(Name, LoweredName) SELECT Name, LOWER(Name) FROM inserted 
END; 

Теперь, если я пытаюсь вставить запись:

dc.Names.Add(new A { Name = "Test" }); 
dc.SaveChanges(); 

Я получаю следующее сообщение об ошибке:

Store update, insert, or delete statement affected an unexpected number of rows (0). Entities may have been modified or deleted since entities were loaded. Refresh ObjectStateManager entries. 

Любые идеи, как обойти это? Все мои классы наследуют от базового класса, который имеет столбец RowVersion (Timestamp). Не могу ли я использовать такой простой триггер с EF при использовании параллелизма в поле timestamp?

Обновлено

Существует первичный ключ (также добавили его в приведенном выше примере).

Update 2

Это из SQL Profiler:

declare @0 nvarchar(100) 
set @0=N'Test' 
insert [dbo].[abc]([Name], [LoweredCompanyName]) values (@0, null) 
select [Id], [RowVersion] from [dbo].[Abc] where @@ROWCOUNT > 0 and [Id] = scope_identity() 

Проблема заключается в том, что выбор не возвращает ничего.

+0

Вы действительно получаете сообщение об ошибке, когда вы вызываете SaveChanges или позже в коде? –

+0

Когда он пытается выполнить SaveChanges(). – Patrick

+0

Действительно ли ваш триггер не вставляет RowVersion или это просто упрощение? –

ответ

1

У этого объекта нет первичного ключа. EF это не понравится.

Для устранения текущей ошибки попробуйте добавить это в конце вашего триггера:

SELECT @@ROWCOUNT 

Если вы измените свой код для поддержки автогенерируемых ПК, вы будете использовать вместо этого:

SELECT SCOPE_IDENTITY() 

Я не уверен, будет ли это работать вместо триггера, но это было необходимо при сопоставлении хранимых процедур с операциями модификации в EDMX.

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

+0

Я оставил это только для простоты класса. Он имеет первичный ключ. См. Выше, я обновил вопрос. – Patrick

+0

Итак, что произойдет, если вы попытаетесь выбрать идентификатор области с помощью триггера? –

+0

Затем я получаю это сообщение «Член с идентификатором» не существует в коллекции метаданных. \ R \ nПараметр: идентификатор « – Patrick

1

@ Патрик

Попробуйте

SELECT SCOPE_IDENTITY() as [EXAMPLE] 

Где [Пример] является именем столбца идентификации

я имел такую ​​же проблему, и это работает для меня.

1
CREATE TRIGGER IOI_LoweredName 
    ON Abc 
    INSTEAD OF INSERT 
AS; 
BEGIN; 
    SET NOCOUNT ON; 

    INSERT INTO Abc(Name, LoweredName) 
    OUTPUT INSERTED.Id,INSERTED.RowVersion, 
    SELECT Name, LOWER(Name) 
    FROM inserted 
END;