[英]Problem when calling the Stored Procedure in Console application using EF6
[英]Stored procedure working when calling exec sp and throws with EF6 on SQL Azure
我有這個存儲過程
CREATE PROCEDURE [dbo].[sp_RebuildIndexes]
AS
BEGIN
DECLARE @TableName varchar(255)
DECLARE TableCursor CURSOR FOR (SELECT
'[' + IST.TABLE_SCHEMA + '].[' + IST.table_name + ']' AS [TableName]
FROM INFORMATION_SCHEMA.TABLES IST
WHERE IST.TABLE_TYPE = 'BASE TABLE')
OPEN
TableCursor
FETCH NEXT FROM TableCursor INTO @TableName
WHILE @@fetch_status = 0
BEGIN
PRINT ('Rebuilding Indexes on ' + @TableName)
BEGIN TRY
EXEC ('ALTER INDEX ALL ON ' + @TableName + ' REBUILD with (ONLINE=ON)')
END TRY
BEGIN CATCH
PRINT ('Cannot do rebuild with Online=On option, taking table ' + @TableName + ' down for doing rebuild')
EXEC ('ALTER INDEX ALL ON ' + @TableName + ' REBUILD')
END CATCH
FETCH NEXT FROM TableCursor INTO @TableName
END
CLOSE TableCursor
DEALLOCATE TableCursor
END
如果我使用SQL查詢執行它
exec [dbo].[sp_RebuildIndexes]
工作正常。
現在使用此代碼從EF6調用它可以在SQL Azure上拋出,但可以在localdb上運行:
var sqlConnection = (SqlConnection) _context.Database.Connection;
sqlConnection.InfoMessage += (s, m) => messages = m.Message;
_context.Database.ExecuteSqlCommand("exec [dbo].[sp_RebuildIndexes]");
例外:
The current transaction cannot be committed and cannot support operations that write to the log file. Roll back the transaction.
The current transaction cannot be committed and cannot support operations that write to the log file. Roll back the transaction.
The current transaction cannot be committed and cannot support operations that write to the log file. Roll back the transaction.
Uncommittable transaction is detected at the end of the batch. The transaction is rolled back.
[SqlException (0x80131904): The current transaction cannot be committed and cannot support operations that write to the log file. Roll back the transaction.
您對出什么問題有任何線索嗎?
編輯:
僅在無法使用ONLINE = ON重建索引的情況下才會出現問題
編輯2:如果我將此sp與SqlConnection對象一起使用,則它可以正常工作。
最后是解決方法:
我懷疑是一個事務問題,經過更多調查后,發現問題出在這里:如果您在此處查看http://msdn.microsoft.com/en-us/data/dn456843
默認情況下,從EF6開始,Database.ExecuteSqlCommand()會將命令包裝在事務中(如果尚不存在)。 此方法有很多重載,允許您在需要時覆蓋此行為。 同樣,在EF6中,通過諸如ObjectContext.ExecuteFunction()之類的API執行包含在模型中的存儲過程也是如此(但當前無法覆蓋默認行為)。
所以更換
_context.Database.ExecuteSqlCommand("exec [dbo].[sp_RebuildIndexes]");
同
_context.Database.ExecuteSqlCommand(TransactionalBehavior.DoNotEnsureTransaction, "exec [dbo].[sp_RebuildIndexes]");
而且有效!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.