在我們的單元測試中,我們使用普通的ADO.NET(DataTable,DataAdapter)來準備數據庫響應。檢查結果,而測試的組件本身在NHibernate 2.1下運行。 .NET版本是3.5,SqlServer版本是2005.DataTable標識列未在DataAdapter.Update/Refresh之後設置,使用「 - 」代替「-trigger」(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包裝產生)insert語句嘗試檢索標識值回的DataRow:
exec sp_executesql N'
insert into emp (...) values (...);
select id, ... from emp where id = @@identity
'
但DataRow中的id-列仍然是0。當我暫時移除了扳機,它工作正常 - 然後在ID列保存數據庫設置標識值。
NHibernate的,另一方面採用這種INSERT語句:
exec sp_executesql N'
insert into emp (...) values (...);
select scope_identity()
'
這工作,NHibernate的POCO有沖洗之後正確地設置其ID屬性。這對我來說似乎有點反直覺,因爲我期望觸發器在不同的範圍內運行,因此@@身份應該比scope_identity()更適合。
所以我認爲沒有問題,我將在ADO.NET下應用scope_identity()而不是@@ identity。但是這沒有效果,DataRow值仍然沒有相應更新。
現在最好的部分是:當我從SqlServer分析器中將這兩個語句複製並粘貼到Management Studio查詢(包括「exec sp_executesql」)中,並在那裏運行它們時,結果似乎相反!那裏的ADO.NET版本工作,和NHibernate版本不(選擇scope_identity()返回null)。我試了幾次來驗證,但無濟於事。那麼,實際上這就是我所期望的 - @@身份確定,而scope_identity()失敗。
當然,在Management Studio中調用它只是顯示來自數據庫的結果集,無論在NHibernate和ADO.NET中發生的是另一個主題。另外,T-SQL SET定義的幾個會話屬性在兩種情況下是不同的(Management Studio查詢與運行時應用程序)
這對我來說是一個真正的難題。我會很高興有關這方面的任何見解。謝謝!