Сохраненная процедура, работающая при вызове exec sp и throws с EF6 на SQL Azure

azure-sql-database c# entity-framework entity-framework-6 stored-procedures

Вопрос

У меня есть эта хранимая процедура

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

EDIT 2: Если я использую этот sp с объектом SqlConnection, он работает.

Принятый ответ

Наконец, это исправление:

Я подозревал, что проблема с транзакцией, и после нескольких исследований здесь возникает проблема: если вы проверите здесь http://msdn.microsoft.com/en-us/data/dn456843

Начиная с EF6 Database.ExecuteSqlCommand () по умолчанию будет завершена команда в транзакции, если ее еще нет. Есть перегрузки этого метода, которые позволяют вам переопределить это поведение, если хотите. Также в EF6 выполнение хранимых процедур, включенных в модель через API, таких как ObjectContext.ExecuteFunction () делает то же самое (за исключением того, что поведение по умолчанию в настоящий момент не может быть переопределено).

Таким образом, заменяя

_context.Database.ExecuteSqlCommand("exec [dbo].[sp_RebuildIndexes]");

С

_context.Database.ExecuteSqlCommand(TransactionalBehavior.DoNotEnsureTransaction, "exec [dbo].[sp_RebuildIndexes]");

И это работает!




Лицензировано согласно: CC-BY-SA with attribution
Не связан с Stack Overflow
Является ли этот КБ законным? Да, узнайте, почему
Лицензировано согласно: CC-BY-SA with attribution
Не связан с Stack Overflow
Является ли этот КБ законным? Да, узнайте, почему