👋 Nový obsah na borekb.cz

Info Tento blog je v "read-only módu" a nový obsah již nebude přibývat. O vývoji píšu na DevBlog.

There is already an open DataReader associated with this Command which must be closed first

Představte si následující kód, ve kterém je využíváno jediné připojení k databázi (detaily jsou vynechány):

reader = command.ExecuteReader();
while (reader.Read()) {
  ...
  updateCommand.ExecuteNonQuery();
  ...
}

Tento kód skončí výjimkou „There is already an open DataReader associated with this Command which must be closed first“.

První věcí je, že popis výjimky moc vývojáři nepomůže. Zpráva totiž napovídá, že je s jedním Commandem asociováno víc DataReaderů, což ale na první pohled není pravda – jediný otevřený DataReader je asociován s objektem command, který není totožný s objektem updateCommand. Navíc vykonáváme ExecuteNonQuery a žádného DataReadera nevytváříme. Pro začátečníka mého typu je tedy hláška zcela k ničemu, naopak je spíše matoucí. (V souvislosti s tím doporučuji shlédnout skvělý track PRS223: Getting Users to Fall in Love with Your Software: 2005 Editionvideí z PDC 05, kde se na téma zbytečných hlášek pobavíte a poučíte zároveň.) Jen pro úplnost poznamenám, že hláška svůj smysl má, protože oba objekty command jsou propojeny přes objekt Connection a DataReader se vytváří i při ExecuteNonQuery, protože tento příkaz vrací počet ovlivněných řádků. Ale to je celkem jedno, hláška prostě dobrá není.

Co s tím, navíc když v .NET Frameworku beta 2 stejný kód hladce fungoval? První možností je použít workaroundpříslušného bug reportu, ale elegantnější možností je trochu pozměnit connection string. Pes je totiž zakopaný v tom, že v RTM verzi .NETu dvojky je MARS defaultně vypnutý (na rozdíl od bety 2), takže je potřeba do connection stringu přidat MultipleActive­ResultSets=Tru­e.

A je to.

Zařazeno do kategorií |
rarouš (Út, 2006-01-17 07:45):

Dík za info, třeba se to bude někdy hodit :)

Borek (Út, 2006-01-17 09:50):

Včera jsem taky ještě narazil na jednu vychytávku s parametrizovanými dotazy (UPDATE MyTable SET ColName = @ColValue…), která na webu není skoro vůbec popsána a stála mě dost nervů. ASP.NET občas trochu zlobí..

Nikisbeta (St, 2006-01-18 20:51):

Děkuji za radu, trapil jsem se s timto problemem celý den, ale nevyřešil jsem ho HEH. Bohužel jsem nucen použivat MS SQL server 2000 (7.0) ve kterém MultipleActive­ResultSet neni podporován, což se člověk po dlouhem bádání dočte i na Microsoftu. Nevíte prosím jak tento problem vyřešit u této verze SQL serveru. Mnohokrát díky

Borek (Čt, 2006-01-19 09:23):

Nevíte prosím jak tento problem vyřešit u této verze SQL server

Otevřít víc připojení (SqlConnection).

Jarda Jirava (Čt, 2006-01-26 17:14):

Hodne zalezi co presne s daty delas, ale pokud nacitanych dat neni mnoho, radeji bych pouzil DataTable a tu naplnil a pote iteraci pres ni provadel update. Vyhnes se tak mozneho zamku nad nacitanou tabulkou, ktere muze vest k deadlocku v pripade vice spojeni. – J.

David Máj (Čt, 2006-09-28 22:13):

Prave mi tento problem nastal. Diky za info. :)

Petr (Po, 2007-09-03 22:49):

Právě jsem se s tímto problémkem setkal.. po pár minutách, kdy jsem neustále kontroloval kód, jsem tu skvělou chybovou hlášku zadal do Googlu a ejhle! u Borka je řešení.. takže díky za nakopnutí.

Komentáře jsou uzavřeny (blog je v read-only módu). Pokud mě chcete kontaktovat, můžete mailem.