Уже существует открытый DataReader, связанный с этой командой, который должен быть закрыт первым - PullRequest
565 голосов
/ 19 мая 2011

У меня есть этот запрос, и я получаю сообщение об ошибке в этой функции:

var accounts = from account in context.Accounts
               from guranteer in account.Gurantors
               select new AccountsReport
               {
                   CreditRegistryId = account.CreditRegistryId,
                   AccountNumber = account.AccountNo,
                   DateOpened = account.DateOpened,
               };

 return accounts.AsEnumerable()
                .Select((account, index) => new AccountsReport()
                    {
                        RecordNumber = FormattedRowNumber(account, index + 1),
                        CreditRegistryId = account.CreditRegistryId,
                        DateLastUpdated = DateLastUpdated(account.CreditRegistryId, account.AccountNumber),
                        AccountNumber = FormattedAccountNumber(account.AccountType, account.AccountNumber)
                    })
                .OrderBy(c=>c.FormattedRecordNumber)
                .ThenByDescending(c => c.StateChangeDate);


public DateTime DateLastUpdated(long creditorRegistryId, string accountNo)
{
    return (from h in context.AccountHistory
            where h.CreditorRegistryId == creditorRegistryId && h.AccountNo == accountNo
            select h.LastUpdated).Max();
}

Ошибка:

Уже есть открытый DataReader, связанный с этой командой, который должен быть закрыт первым.

Обновление:

добавлена ​​трассировка стека:

InvalidOperationException: There is already an open DataReader associated with this Command which must be closed first.]
   System.Data.SqlClient.SqlInternalConnectionTds.ValidateConnectionForExecute(SqlCommand command) +5008639
   System.Data.SqlClient.SqlConnection.ValidateConnectionForExecute(String method, SqlCommand command) +23
   System.Data.SqlClient.SqlCommand.ValidateCommand(String method, Boolean async) +144
   System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, DbAsyncResult result) +87
   System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method) +32
   System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior, String method) +141
   System.Data.SqlClient.SqlCommand.ExecuteDbDataReader(CommandBehavior behavior) +12
   System.Data.Common.DbCommand.ExecuteReader(CommandBehavior behavior) +10
   System.Data.EntityClient.EntityCommandDefinition.ExecuteStoreCommands(EntityCommand entityCommand, CommandBehavior behavior) +443

[EntityCommandExecutionException: An error occurred while executing the command definition. See the inner exception for details.]
   System.Data.EntityClient.EntityCommandDefinition.ExecuteStoreCommands(EntityCommand entityCommand, CommandBehavior behavior) +479
   System.Data.Objects.Internal.ObjectQueryExecutionPlan.Execute(ObjectContext context, ObjectParameterCollection parameterValues) +683
   System.Data.Objects.ObjectQuery`1.GetResults(Nullable`1 forMergeOption) +119
   System.Data.Objects.ObjectQuery`1.System.Collections.Generic.IEnumerable<T>.GetEnumerator() +38
   System.Linq.Enumerable.Single(IEnumerable`1 source) +114
   System.Data.Objects.ELinq.ObjectQueryProvider.<GetElementFunction>b__3(IEnumerable`1 sequence) +4
   System.Data.Objects.ELinq.ObjectQueryProvider.ExecuteSingle(IEnumerable`1 query, Expression queryRoot) +29
   System.Data.Objects.ELinq.ObjectQueryProvider.System.Linq.IQueryProvider.Execute(Expression expression) +91
   System.Data.Entity.Internal.Linq.DbQueryProvider.Execute(Expression expression) +69
   System.Linq.Queryable.Max(IQueryable`1 source) +216
   CreditRegistry.Repositories.CreditRegistryRepository.DateLastUpdated(Int64 creditorRegistryId, String accountNo) in D:\Freelance Work\SuperExpert\CreditRegistry\CreditRegistry\Repositories\CreditRegistryRepository.cs:1497
   CreditRegistry.Repositories.CreditRegistryRepository.<AccountDetails>b__88(AccountsReport account, Int32 index) in D:\Freelance Work\SuperExpert\CreditRegistry\CreditRegistry\Repositories\CreditRegistryRepository.cs:1250
   System.Linq.<SelectIterator>d__7`2.MoveNext() +198
   System.Linq.Buffer`1..ctor(IEnumerable`1 source) +217
   System.Linq.<GetEnumerator>d__0.MoveNext() +96

Ответы [ 18 ]

1 голос
/ 21 июля 2017

Для тех, кто нашел это через Google;
Я получал эту ошибку, потому что, как подсказывает ошибка, мне не удалось закрыть SqlDataReader перед созданием другого на той же SqlCommand, ошибочно полагая, что это будет сборщик мусора, когдаоставив метод, в котором он был создан.

Я решил проблему, вызвав sqlDataReader.Close(); перед созданием второго считывателя.

1 голос
/ 21 июля 2017

Я решил эту проблему, изменив await _accountSessionDataModel.SaveChangesAsync (); в _accountSessionDataModel.SaveChanges (); в моем классе репозитория.

 public async Task<Session> CreateSession()
    {
        var session = new Session();

        _accountSessionDataModel.Sessions.Add(session);
        await _accountSessionDataModel.SaveChangesAsync();
     }

Изменено:

 public Session CreateSession()
    {
        var session = new Session();

        _accountSessionDataModel.Sessions.Add(session);
        _accountSessionDataModel.SaveChanges();
     }

Проблема заключалась в том, что я обновил Sessions во внешнем интерфейсе после создания сеанса (в коде), но поскольку SaveChangesAsync происходит асинхронно, выборка сеансов вызвала эту ошибку, поскольку, очевидно, операция SaveChangesAsync еще не была готова.

1 голос
/ 02 июня 2016

У меня была такая же ошибка, когда я пытался обновить некоторые записи в цикле чтения. Я попытался получить наиболее голосующий ответ MultipleActiveResultSets=true и обнаружил, что это просто обходной путь для получения следующей ошибки

Новая транзакция не разрешена, потому что запущены другие потоки в сеансе

Лучший подход, который будет работать для огромных ResultSets, - это использовать чанки и открывать отдельный контекст для каждого чанка, как описано в SqlException из Entity Framework - Новая транзакция не разрешена, поскольку в сеансе запущены другие потоки

0 голосов
/ 05 марта 2019

В моем случае мне пришлось установить MultipleActiveResultSets на True в строке подключения.
Затем появилась другая ошибка (настоящая) о невозможности выполнить 2 (SQL) команды нав то же время в том же контексте данных!(EF Core, сначала код)
Таким образом, для меня было решение найти любую другую асинхронную команду выполнения и превратить их в синхронную , так как у меня был только один DbContext для обоихкоманды.

Я надеюсь, что это поможет вам

0 голосов
/ 23 октября 2018

Как примечание ... это также может произойти, когда есть проблема с (внутренним) отображением данных из объектов SQL.

Например ...

Я создалSQL Scalar Function, что случайно вернул VARCHAR ... и затем ... использовал его для генерации столбца в VIEW.VIEW был правильно отображен в DbContext ... так что Linq вызывал его просто отлично.Однако Entity ожидаемый DateTime? и VIEW возвращали String .

Какие ODDLY выбрасывает ...

"Уже есть открытый DataReader, связанный с этой командой, который должен быть закрыт первым"

Это было трудночтобы выяснить ... но после того, как я исправил возвращаемые параметры ... все было хорошо

0 голосов
/ 06 сентября 2017

Это извлечено из сценария реального мира:

  • Код хорошо работает в среде Stage с MultipleActiveResultSets, установлен в строке подключения
  • Код опубликован в производственной среде без MultipleActiveResultSets =true
  • Так много страниц / вызовов работает, пока не работает ни одна
  • Если присмотреться к вызову, ненужный вызов сделан дляБД и ее необходимо удалить
  • Установить MultipleActiveResultSets = true в Производственный и опубликовать очищенный код, все работает хорошо и, эффективно

В заключение, не забывая о MultipleActiveResultSets, кодвозможно, долго выполнялся, прежде чем обнаружил избыточный вызов БД, который мог бы быть очень дорогостоящим, и я предлагаю не полностью зависеть от установки атрибута MultipleActiveResultSets, но также выяснить, зачем он нужен коду в случае его сбоя .

0 голосов
/ 26 июля 2017

Ну, для меня это был мой собственный баг. Я пытался запустить INSERT, используя SqlCommand.executeReader(), когда я должен был использовать SqlCommand.ExecuteNonQuery(). Он был открыт и никогда не закрывался, вызывая ошибку. Остерегайтесь этого упущения.

0 голосов
/ 28 декабря 2015

Я использую веб-сервис в своем инструменте, где эти сервисы извлекают хранимую процедуру. в то время как большее количество клиентских инструментов извлекает веб-сервис, эта проблема возникает. Я исправил, указав атрибут Synchronized для этих функций, извлекает хранимую процедуру. теперь он работает нормально, ошибка никогда не обнаруживалась в моем инструменте.

 [MethodImpl(MethodImplOptions.Synchronized)]
 public static List<t> MyDBFunction(string parameter1)
  {
  }

Этот атрибут позволяет обрабатывать один запрос за раз. так что это решает проблему.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...