2017-08-29 47 views
0

我有呼叫使用EF這樣的存儲過程需要一些時間來執行(〜60秒):從實體框架6的異常行爲調用存儲過程

context.Database.ExecuteSqlCommand(
    "myStoredProcedure @param1", 
    new SqlParameter("param1", param1) 
); 

該存儲的過程包括兩個部分:

  1. 插入新行到表tblSomeTable事後

  2. 計算從多個表中的一些信息是不要包括tblSomeTable

第二個操作是耗時的。當我從SSMS執行此存儲過程我可以看到,一個新行程序完成執行這是一個正常的行爲之前加入到tblSomeTable,但是,當我使用上述代碼然後一個新行中運行相同的確切過程僅當過程完成執行時纔會添加tblSomeTable

此外,在程序運行時,我根本無法查詢tblSomeTable(均來自EF和SSMS),從我認爲鎖定tblSomeTable直到過程結束。這是爲什麼發生?

這是SQL Server 2008的

+0

您的ExecuteSqlCommand工作是否成功?你只想知道在運行命令時你可以看到tblSomeTable中的數據?對? – CodeNotFound

+0

是的,它是的,是的,我只想看到tblSomeTable中的行。 (在過程完成之前) – astralmaster

回答

0

這究竟是爲什麼?

這並不是異常行爲。您看不到插入到tblSomeTable中的數據,因爲當您調用context.Database.ExecuteSqlCommand時,會創建一個新的SQL Server事務。這就是documentation說:

如果沒有一個現有的本地或環境事務新的事務將被用於執行命令。

,並用於通過EF交易的默認隔離級別是爲序列化最高。這意味着任何在事務外部執行的SQL查詢都無法看到當事務未提交時當前插入到tblSomeTable中的任何數據。當您的context.Database.ExecuteSqlCommand未完成其工作時,您在SSMS中執行的查詢將無法看到數據。

您可以更改隔離級別,但我不建議這樣做,如果那唯一的目的是檢查什麼叫context.Database.ExecuteSqlCommand當你的存儲過程做。後

編輯@大衛布朗 - 微軟評論:

EF的默認隔離級別爲READ COMMITTED,而不是SERIALIZABLE正如我上面所說。無法讀取未提交的數據仍然適用。從documentation

定義:

指定語句不能讀取已修改但 沒有其他事務提交的數據。這可以防止髒讀。數據 可以通過當前事務內的單個語句 之間的其他事務進行更改,從而導致不可重複的讀取或 幻影數據。該選項是SQL Server的默認值。

+1

注意EF默認情況下不使用可序列化事務。只是正常閱讀承諾。 –

+0

@ DavidBrowne- Microsoft感謝。更新了我的答案。 – CodeNotFound

0

上按照documentation

與EF6 Database.ExecuteSqlCommand()默認情況下,開始將在交易包住命令如果一個人不存在

所以你不會看到任何SSMS修改,直到它結束。