В наших модульных тестах мы используем простой ADO.NET (DataTable, DataAdapter) для подготовки базы данных, соответственно. проверка результатов, в то время как сами протестированные компоненты работают под NHibernate 2.1. Версия .NET - 3.5, версия SqlServer - 2005.
Таблицы базы данных имеют идентичные столбцы в качестве первичных ключей. Некоторые таблицы применяют триггеры вместо вставки / обновления (это связано с обратной совместимостью, я ничего не могу изменить). Триггеры обычно работают так:
create trigger dbo.emp_insert
on dbo.emp
instead of insert
as
begin
set nocount on
insert into emp ...
select @@identity
end
Оператор вставки, выданный ADO.NET DataAdapter (сгенерированный на лету тонкой оболочкой ADO.NET), пытается извлечь значение идентификатора обратно в DataRow:
exec sp_executesql N'
insert into emp (...) values (...);
select id, ... from emp where id = @@identity
'
Но id-столбец DataRow по-прежнему равен 0. Когда я временно удаляю триггер, он работает нормально - тогда столбец id хранит значение идентификатора, установленное базой данных.
С другой стороны, NHibernate использует такой оператор вставки:
exec sp_executesql N'
insert into emp (...) values (...);
select scope_identity()
'
Это работает, у свойства NHibernate POCO свойство id установлено правильно сразу после сброса. Это кажется мне немного нелогичным, так как я ожидал, что триггер будет работать в другой области видимости, поэтому @@ identity должно подходить лучше, чем scope_identity ().
Так что я подумал, что нет проблем, я буду применять scope_identity () вместо @@ identity в ADO.NET. Но это не имеет никакого эффекта, значение DataRow по-прежнему не обновляется соответствующим образом.
А теперь самое главное: когда я копирую и вставляю эти два оператора из профилировщика SqlServer в запрос Management Studio (включая exec sp_executesql) и запускаю их там, результаты кажутся обратными! Там работает версия ADO.NET, а версия NHibernate - нет (select scope_identity () возвращает null). Я несколько раз пытался проверить, но безрезультатно. Ну, на самом деле это было то, чего я ожидал - @@ identity будет в порядке, а scope_identity () завершится ошибкой.
Конечно, его вызов в Management Studio просто показывает набор результатов, поступающий из базы данных, что бы ни происходило внутри NHibernate, а ADO.NET - другая тема. Кроме того, некоторые свойства сеанса, определенные в T-SQL SET, отличаются в двух сценариях (запрос Management Studio и приложение во время выполнения)
Это настоящая головоломка для меня. Я был бы рад любому пониманию этого. Спасибо!