Er is al een open datawaar geassocieerd met deze opdracht die eerst moet worden gesloten

Ik heb deze query en ik krijg de fout in deze functie:

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();
}

FOUT IS:

Er is al een open datareader geassocieerd met deze opdracht die eerst moet worden gesloten.

update:

Stack Trace Toegevoegd:

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

Antwoord 1, autoriteit 100%

Dit kan gebeuren als u een query uitvoert terwijl u de resultaten van een andere query herhaalt. Het is uit uw voorbeeld niet duidelijk waar dit gebeurt omdat het voorbeeld niet volledig is.

Een ding dat dit kan veroorzaken, is lui laden dat wordt geactiveerd wanneer de resultaten van een zoekopdracht worden herhaald.

Dit kan eenvoudig worden opgelost door MARS toe te staan in uw verbindingsreeks. Voeg MultipleActiveResultSets=truetoe aan het providergedeelte van uw verbindingsreeks (waar Gegevensbron, Initiële Catalogus, enz. zijn gespecificeerd).


Antwoord 2, autoriteit 17%

U kunt de methode ToList()gebruiken vóór de instructie return.

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).ToList();
 public DateTime DateLastUpdated(long creditorRegistryId, string accountNo)
    {
        var dateReported = (from h in context.AccountHistory
                            where h.CreditorRegistryId == creditorRegistryId && h.AccountNo == accountNo
                            select h.LastUpdated).Max();
        return dateReported;
    }

Antwoord 3, autoriteit 3%

gebruik de syntaxis .ToList()om het gelezen object van db naar lijst te converteren om te voorkomen dat het opnieuw wordt gelezen. Ik hoop dat dit ervoor werkt. Bedankt.


Antwoord 4, autoriteit 2%

Hier is een werkende verbindingsreeks voor iemand die referentie nodig heeft.

<connectionStrings>
  <add name="IdentityConnection" connectionString="Data Source=(LocalDb)\v11.0;AttachDbFilename=|DataDirectory|\IdentityDb.mdf;Integrated Security=True;MultipleActiveResultSets=true;" providerName="System.Data.SqlClient" />
</connectionStrings>

Antwoord 5, autoriteit 2%

In mijn geval loste het gebruik van Include()deze fout op en afhankelijk van de situatie kan het een stuk efficiënter zijn dan het geven van meerdere query’s wanneer het allemaal tegelijk kan worden opgevraagd met een join.

IEnumerable<User> users = db.Users.Include("Projects.Tasks.Messages");
foreach (User user in users)
{
    Console.WriteLine(user.Name);
    foreach (Project project in user.Projects)
    {
        Console.WriteLine("\t"+project.Name);
        foreach (Task task in project.Tasks)
        {
            Console.WriteLine("\t\t" + task.Subject);
            foreach (Message message in task.Messages)
            {
                Console.WriteLine("\t\t\t" + message.Text);
            }
        }
    }
}

Antwoord 6

Ik weet niet of dit een dubbel antwoord is of niet. Als dat zo is, spijt het me. Ik wil de behoeftigen laten weten hoe ik mijn probleem heb opgelost met ToList().

In mijn geval kreeg ik dezelfde uitzondering voor onderstaande zoekopdracht.

int id = adjustmentContext.InformationRequestOrderLinks.Where(
             item => item.OrderNumber == irOrderLinkVO.OrderNumber 
                  && item.InformationRequestId == irOrderLinkVO.InformationRequestId)
             .Max(item => item.Id);

Ik heb het opgelost zoals hieronder

List<Entities.InformationRequestOrderLink> links = 
      adjustmentContext.InformationRequestOrderLinks
           .Where(item => item.OrderNumber == irOrderLinkVO.OrderNumber 
                       && item.InformationRequestId == irOrderLinkVO.InformationRequestId)
           .ToList();
int id = 0;
if (links.Any())
{
  id = links.Max(x => x.Id);
}
if (id == 0)
{
//do something here
}

Antwoord 7

Het lijkt erop dat u DateLastUpdated aanroept vanuit een actieve query met dezelfde EF-context en DateLastUpdate geeft een opdracht aan het gegevensarchief zelf. Entity Framework ondersteunt slechts één actieve opdracht per context tegelijk.

U kunt uw bovenstaande twee zoekopdrachten als volgt omzetten in één:

return accounts.AsEnumerable()
        .Select((account, index) => new AccountsReport()
        {
          RecordNumber = FormattedRowNumber(account, index + 1),
          CreditRegistryId = account.CreditRegistryId,
          DateLastUpdated = (
                                                from h in context.AccountHistory 
                                                where h.CreditorRegistryId == creditorRegistryId 
                              && h.AccountNo == accountNo 
                                                select h.LastUpdated).Max(),
          AccountNumber = FormattedAccountNumber(account.AccountType, account.AccountNumber)
        })
        .OrderBy(c=>c.FormattedRecordNumber)
        .ThenByDescending(c => c.StateChangeDate);

Ik heb ook gemerkt dat u functioneert zoals opmaak- en opmaak -CordNumber in de query’s. Tenzij deze zijn opgeslagen Procs of -functies die u uit uw database hebt geïmporteerd in het entiteitsgegevensmodel en de juiste in kaart gebracht, zullen deze ook uitzonderingen gooien, omdat EF niet weet hoe u die functies wilt vertalen naar uitspraken die het naar de Data Store kan verzenden.

Noteer ook, het bellen van aseenvolle forceert de query niet om uit te voeren. Totdat de uitvoering van de query wordt uitgesteld totdat hij is opgesomd. Je kunt de opsomming van Tolist of Toarray forceren als je dat wenst.


8

In mijn geval had ik een query geopend van data-context, zoals

   Dim stores = DataContext.Stores _
        .Where(Function(d) filter.Contains(d.code)) _

… en vervolgens verschijnt vervolgens dezelfde …

   Dim stores = DataContext.Stores _
        .Where(Function(d) filter.Contains(d.code)).ToList

Voeg de .ToListtoe aan de eerste opgelost mijn probleem. Ik denk dat het logisch is om dit in een eigendom te wikkelen zoals:

Public ReadOnly Property Stores As List(Of Store)
    Get
        If _stores Is Nothing Then
            _stores = DataContext.Stores _
                .Where(Function(d) Filters.Contains(d.code)).ToList
        End If
        Return _stores
    End Get
End Property

Waar _stores een particuliere variabele is, en filters is ook een readonly-eigenschap die leest van appsettings.


9

Naast ladislav mrnka’s antwoord:

Als u de container publiceert en overschrijft op het tabblad Instellingen, kunt u MultipleActiveResultSetinstellen op True. Je kunt deze optie vinden door op Geavanceerd…te klikken en het zal onder de groep Geavanceerdstaan.


Antwoord 10

Ik heb dit probleem opgelost door te wijzigen
wacht op _accountSessionDataModel.SaveChangesAsync();
tot
_accountSessionDataModel.SaveChanges();
in mijn Repository-klas.

public async Task<Session> CreateSession()
    {
        var session = new Session();
        _accountSessionDataModel.Sessions.Add(session);
        await _accountSessionDataModel.SaveChangesAsync();
     }

Gewijzigd in:

public Session CreateSession()
    {
        var session = new Session();
        _accountSessionDataModel.Sessions.Add(session);
        _accountSessionDataModel.SaveChanges();
     }

Het probleem was dat ik de Sessions in de frontend heb bijgewerkt na het maken van een sessie (in code), maar omdat SaveChangesAsync asynchroon gebeurt, veroorzaakte het ophalen van de sessies deze fout omdat de SaveChangesAsync-bewerking blijkbaar nog niet gereed was.


Antwoord 11

Voor degenen die dit via Google vinden;
Ik kreeg deze fout omdat ik, zoals de fout suggereerde, er niet in slaagde een SqlDataReader te sluiten voordat ik een andere op dezelfde SqlCommand maakte, ten onrechte aangenomen dat het afval zou worden verzameld bij het verlaten van de methode waarin het is gemaakt.

Ik heb het probleem opgelost door sqlDataReader.Close();aan te roepen voordat ik de tweede lezer maakte.


Antwoord 12

Als een kanttekening… dit kan ook gebeuren als er een probleem is met (interne) data-mapping vanuit SQL Objects.

Bijvoorbeeld…

Ik heb een SQL Scalar Functiongemaakt die per ongelukeen VARCHARretourneerde… een VIEW. De VIEWwas correct in kaart gebracht in de DbContext…dus Linqnoemde het prima. De Entiteitverwachtte echter DateTime?en de VIEWretourneerde String.

Welke ODDLY gooit…

“Er is al een open DataReader gekoppeld aan deze opdracht
die eerst moet worden gesloten”

Het was moeilijk te achterhalen… maar nadat ik de retourparameters had gecorrigeerd… was alles in orde


Antwoord 13

Ik had dezelfde fout toen ik probeerde enkele records in de leeslus bij te werken.
Ik heb de meest gestemde answer MultipleActiveResultSets=truegeprobeerd en ontdekte dat het slechts een tijdelijke oplossing is om de volgende fout te krijgen 

Nieuwe transactie is niet toegestaan omdat er andere threads actief zijn
in de sessie

De beste aanpak, die werkt voor enorme ResultSets, is om chunks te gebruiken en een aparte context te openen voor elke chunk, zoals beschreven in 
SqlException van Entity Framework – Nieuw transactie is niet toegestaan omdat er andere threads in de sessie lopen


Antwoord 14

Nou, voor mij was het mijn eigen bug. Ik probeerde een INSERTuit te voeren met SqlCommand.executeReader()terwijl ik SqlCommand.ExecuteNonQuery()had moeten gebruiken. Het werd geopend en nooit gesloten, waardoor de fout werd veroorzaakt. Pas op voor dit onoplettendheid.


Antwoord 15

Dit is afgeleid van een realistisch scenario:

  • Code werkt goed in een Stage-omgeving waarbij MultipleActiveResultSets is ingesteld in de verbindingsreeks
  • Code gepubliceerd in productieomgeving zonder MultipleActiveResultSets=true
  • Zoveel pagina’s/oproepen werken terwijl een enkele niet werkt
  • Als je de oproep van dichterbij bekijkt, is er een onnodige oproepgedaan naar de db en moet deze worden verwijderd
  • Stel MultipleActiveResultSets=true in Productie in en publiceer opgeschoonde code, alles werkt goed en efficiënt

Concluderend, zonder MultipleActiveResultSets te vergeten, kan het zijn dat de code lang heeft gelopen voordat een redundante db-aanroep werd ontdekt die erg duur zou kunnen zijn, en ik raad aan om niet volledig afhankelijk te zijn van het instellen van het MultipleActiveResultSets-kenmerk, maar ook zoek uit waarom de code deze nodig heeft op de plek waar deze is mislukt.


Antwoord 16

Hoogstwaarschijnlijk wordt dit probleem veroorzaakt door de functie “lazy loading” van Entity Framework. Gewoonlijk worden alle samengevoegde gegevens (alles dat in andere databasetabellen is opgeslagen) alleen opgehaald als dat nodig is, tenzij dit expliciet vereist is tijdens het eerste ophalen. In veel gevallen is dat een goede zaak, omdat het voorkomt dat er onnodige gegevens worden opgehaald en zo de queryprestaties verbetert (geen joins) en bandbreedte bespaart.

In de situatie die in de vraag wordt beschreven, wordt de eerste ophaalactie uitgevoerd, en tijdens de “select”-fase wordt gevraagd om ontbrekende lazy loading-gegevens, worden aanvullende vragen gesteld en klaagt EF over “open DataReader”.

De in het geaccepteerde antwoord voorgestelde tijdelijke oplossing maakt uitvoering van deze zoekopdrachten mogelijk, en inderdaad zal het hele verzoek slagen.

Als u echter verzoeken onderzoekt die naar de database zijn verzonden, zult u meerdere verzoeken opmerken – extra verzoek voor elke ontbrekende (lui geladen) gegevens. Dit kan een prestatiemoordenaar zijn.

Een betere aanpak is om te vertellen aan EF om alle benodigde luie geladen gegevens tijdens de eerste query te preload. Dit kan worden gedaan met behulp van “Comlue” -verklaring:

using System.Data.Entity;
query = query.Include(a => a.LazyLoadedProperty);

Op deze manier worden alle benodigde joins uitgevoerd en worden alle benodigde gegevens geretourneerd als een enkele query. Het probleem dat wordt beschreven in de vraag zal worden opgelost.


17

Ik gebruik Web Service in My Tool, waar die dienst de opgeslagen procedure ophalen. Terwijl er meer aantal clienttool de webservice ophaalt, rijst dit probleem. Ik heb vastgezet door het gesynchroniseerde kenmerk op te geven voor die functie haalt de opgeslagen procedure op. Nu werkt het prima, de fout is nooit in mijn tool gebleken.

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

Dit kenmerk maakt het mogelijk om één verzoek tegelijk te verwerken. Dus dit lost het probleem op.

Other episodes