Errore: esiste già un DataReader aperto associato a questo comando che deve essere chiuso per primo

Sto usando una connessione SQL per accedere a diverse tabelle nel mio database. Tuttavia il codice mi restituisce l’errore seguente.

Errore: “Esiste già un DataReader aperto associato a questo comando che deve essere chiuso per primo” :

MyContext conn = new MyContext() protected void ChangeName(int id) { User user = conn.MyOtherTable.First(x => x.id == id); var elements = conn.MyTable.Where(x => x.id == id && x.name == name).OrderBy(x => x.id).OrderBy(x => x.name). .Select(t => new { t.id, t.name, }).GroupBy(t => new { t.id, t.name, }); foreach (var item in elements) { foreach (var row in item) { for (int j = 1; j <= 5; j++) { if (row.name == "name") { user.name1 = row.name; conn.SaveChanges(); } if (row.name == "name2") { user.name2 = row.name; conn.SaveChanges(); } } } } } 

LINQ (quando si parla con un database) è solitamente un’API di spooling non-buffered. Per fare ciò che vuoi, o:

  • abilita più set di risultati attivi (MARS)
  • bufferizzare prima i dati

Preferisco la seconda opzione; richiede semplicemente l’aggiunta di .ToList() alla prima riga:

 var elements = conn.MyTable.Where(x => x.id == id && x.name == name) .OrderBy(x => x.id).OrderBy(x => x.name). .Select(t => new { t.id, t.name, }).GroupBy(t => new { t.id, t.name, }) .ToList(); 

ora, dopo che questa linea è stata eseguita, sappiamo che abbiamo già tutti i dati in memoria e il lettore ha chiuso; in precedenza poteva ancora parlare di input di riga dal lettore.

Per completezza, abilitare MARS è discusso qui – non sarebbe la mia raccomandazione, però.

Conto un errore mentre conti, ma ho triggersto più set di risultati attivi (MARS), infine cambio solo il metodo variabile IDateReader da close () a dispose (), quindi i problemi scompaiono