簡體   English   中英

存儲過程在調用exec sp並在SQL Azure上與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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM