2016-01-06 6 views
4

Я использую Entity Framework для выполнения хранимых процедур (Azure SQL Server) в моей базе данных.Структура объекта: InvalidOperationException: Неверная операция. Соединение закрыто.

Мой C# код выглядит следующим образом:

using (var context = new MyDataContext()) 
    numberOfEffectedRows = context.MySPName(this.Id); 

В большинстве случаев (99,9%) из казней, это работает отлично. Но иногда это не удалось с этой ошибкой:

System.InvalidOperationException: Invalid operation. The connection is closed. 
    at System.Data.SqlClient.SqlInternalConnectionTds.ValidateConnectionForExecute(SqlCommand command) 
    at System.Data.SqlClient.SqlInternalTransaction.Rollback() 
    at System.Data.SqlClient.SqlInternalTransaction.Dispose(Boolean disposing) 
    at System.Data.SqlClient.SqlTransaction.Dispose(Boolean disposing) 
    at System.Data.Entity.Infrastructure.Interception.InternalDispatcher`1.Dispatch[TTarget,TInterceptionContext](TTarget target, Action`2 operation, TInterceptionContext interceptionContext, Action`3 executing, Action`3 executed) 
    at System.Data.Entity.Infrastructure.Interception.DbTransactionDispatcher.Dispose(DbTransaction transaction, DbInterceptionContext interceptionContext) 
    at System.Data.Entity.Core.EntityClient.EntityTransaction.Dispose(Boolean disposing) 
    at System.Data.Entity.Core.Objects.ObjectContext.ExecuteInTransaction[T](Func`1 func, IDbExecutionStrategy executionStrategy, Boolean startLocalTransaction, Boolean releaseConnectionOnSuccess) 
    at System.Data.Entity.Core.Objects.ObjectContext.<>c__DisplayClass4b.<ExecuteFunction>b__49() 
    at System.Data.Entity.SqlServer.DefaultSqlExecutionStrategy.Execute[TResult](Func`1 operation) 
    at System.Data.Entity.Core.Objects.ObjectContext.ExecuteFunction(String functionName, ObjectParameter[] parameters) 
    at ***.MyDataContext.MySPName(Nullable`1 Id) in *** 
    at ***.DoSomething() in *** 

Когда это происходит:

  1. Я не знаю, почему это происходит. Мне кажется рандомизированным.
  2. Я не знаю, было ли выполнено мое «MySPName» или нет.

Кто-то знает, почему это происходит и как я могу узнать, выполняется ли моя хранимая процедура или нет?

+0

фрагмент кода вы вставили один метание исключение? – neo

+0

Да. Согласно StackTrace, строка кода 'context.MySPName (this.Id);' является источником исключения. – No1Lives4Ever

+0

@ No1Lives4Ever Убедитесь, что вы перечислили запрос перед тем, как оставить оператор using, EF использует отложенное выполнение –

ответ

0

Запросы Linq оцениваются лениво. Запрос будет запущен при первом обращении к numberOfEffectedRows. Поскольку вы используете «использование» вокруг создания контекста данных, он становится удаленным после того, как отключается область. Если вы обращаетесь к numberOfEffectedRows за пределами области использования, это произойдет, поскольку запрос не может работать без действительного контекста данных.

+0

В моем коде нет LINQ. Скопировать значение в «numberOfEffectedRows» выполняется «по значению». – No1Lives4Ever

+0

Я все еще думаю, что это как-то связано с вашим использованием утверждения вокруг создания контекста данных из-за всех этих вызовов метода dispose в трассировке стека, а затем пытается проверить соединение. – neo

1

Соединение закрыто из-за тайм-аута, поэтому предлагаю вам проверить ваш Connect Timeout в вашей строке соединения

connectionString="Data Source=..;Initial Catalog=;Persist Security Info=..;User ID=..;Password=..;Connect Timeout=.." 

Для диагностики я предлагаю вам запустить SQL Server Profiler

0

EntityFramework контекст не поточно, возможно, что контекст данных закрыт во время выполнения по какой-то странной причине.

Один из способов справиться с таким сюрпризом - иметь один контекст для каждого запроса.

это самое простое решение, поэтому вы, надеюсь, никогда не столкнетесь с этим исключением.

чек здесь

https://msdn.microsoft.com/en-us/library/microsoft.practices.unity.perrequestlifetimemanager(v=pandp.30).aspx

, что вы можете сделать, это

container.RegisterType<IDataContext, MyDataContext>(new PerRequestLifetimeManager()); 

, а затем вы впрыскивать DataContext где вам нужно получить к нему доступ.

этом контекст автоматически закрывается, когда контейнер расположен

Смежные вопросы