update command a Narušení souběžného zpracování: Událost UpdateCommand ovlivnila 0 z 1 očekávaných záznamů.   otázka

VB.NET, ADO.NET, WinForms, Databáze

Dobrý den,

mám mdb databázi, a tři tabulky, které jsou na sobě závislé relacemi. (VB 2005)

Mám v úmyslu změny ukládat co nejčastěji, aby byla data v databázi mdb co nejdříve aktuální. Tabulky mám zobrazené v komponentách datagridview. Z uvedených důvodů volám při eventu CellEndEdit proceduru, ve které se data z tabulek ukládají:

                Form_Spoje.Validate()

                Form_Spoje.VykresyBindingSource.EndEdit()
                Form_Spoje.VykresyTableAdapter.Update(Form_Spoje.DB_montážkyDataSet.vykresy)

                Form_Spoje.FKvykresyspojeBindingSource.EndEdit()
                Form_Spoje.SpojeTableAdapter.Update(Form_Spoje.DB_montážkyDataSet.spoje)

                Form_Spoje.FKspojeprubehySpojuBindingSource.EndEdit()
                Form_Spoje.PrubehySpojuTableAdapter.Update(Form_Spoje.DB_montážkyDataSet.prubehySpoju)

Skoro bych řekl, že to funguje, ale někdy (zejména při editaci již zadané hodnoty tabulky) dojde k chybě "Narušení souběžného zpracování: Událost UpdateCommand ovlivnila 0 z 1 očekávaných záznamů." V každém případě se to děje nesystematicky a nepravidelně. Možná se snažím ukládat příliš rychle za sebou, možná pro účely okamžitého (nebo velmi častého) ukládání používám hloupou metodu. Prosím pomozte.... Díky Venca.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Podobné hlášky mě už taky párkrát pronásledovaly.

Já používám netypový dataset a pracuji přímo s objekty SQLDataAdapter (mám DB MSSQL), ale princip bude obdobný i u Vašeho typového datasetu s objekty TableAdapter.

Synchronizace dat v objektu DataTable s podkladovou databází se děje prostřednictvím datového adaptéru, který musí mít inicializovány vlastnosti SelectCommand (pro metodu Fill, která tahá data z DB do datasetu) InsertCommand, UpdateCommand a DeleteCommand. V objektu DataTable (který je u Vás přes BindingSource svázán s ovládacím prvkem (zřejmě DataGridView)) se udržuje informace o stavu každého řádku ve vlastnosti RowState. Po načtení dat metodou Fill má každý řádek stav "Unchanged". Pokud do mřížky (a tím automaticky i do DataTable) přidáte řádek, bude mít stav "Added", pokud řádek smažete z mřížky, v objektu Datatable zůstane a bude mít status Deleted, pokud změníte hodnotu v jakékoli buňce, bude mít řádek status "Modified".

Jakmile zavoláte metodu Update datového adapteru, projdou se všechny řádky příslušného objektu DataTable a pro ty, které mají status Added se provede nad databází příkaz, definovaný ve vlastnosti InsertCommand, obdobně DeleteCommand pro smazané řádky a UpdateCommand pro změněné řádky.

Vámi zmiňovaná hláška obecně znamená, že některý ze SQL příkazů nenašel v podkladové databázi řádek, který by vyhovoval WHERE podmínce. U DeleteCommandu to bývá typicky tehdy, když mažete řádek, který už mezitím smazal někdo jiný. U UpdateCommandu to může být způsobeno buď primárním klíčem, nebo složitostí WHERE podmínky v příkazu, který vygeneroval designer či CommandBuilder. Nevím, jak vytváříte primární klíče u nově přidávaných záznamů, zda máte v podkladové DB primární klíč s autoincrementem apod. Často se doporučuje, používat v podkladové DB PK sloupec typu integer s autoincrementem od 1 do kladných hodnot a v datasetu si nastavit u odpovídajícího sloupce autoincrement do záporných hodnot. V InsertCommandu pak tento PK neuvádět s tím, že podkladová DB si jej přiřadí sama. Pokud ale nezavoláte obratem metodu Fill či nepoužijete u UpdateCommandu se vším všudy možnost ovlivnit zpětně právě zpracovávaný objekt DataRow a tím změnit provizorní záporné ID na to skutečné z podkladové DB, pak máte v Datatable řádek s primárním klíčem, který není v DB a tím pádem při následné případné úpravě hodnoty v daném řádku dostanete přesně Vámi uváděnou hlášku.

Navrhuju prověřit manipulaci s primárním klíčem, odchytit si událost RowUpdated datového adaptéru, která se volá po každém jednotlivém příkazu (a dá se zde i vyhodnotit typ chyby a případně nechat program pokračovat), zkontrolovat, jak přesně vypadá vlastní UpdateCommand resp. hlavně jeho WHERE podmínka) a též nesynchronizovat DB při změně v každé buňce, ale třeba až po opuštění řádku (třeba v události RowValidated a testnout si vlastnost IsCurrentRowDirty)

Při použití MSSQL jsou pro primární klíče výhodné sloupce typu uniqueidentifier, které se dají vygenerovat jak na straně serveru, tak v programu a mohou tedy být součástí InsertCommadu.

nahlásit spamnahlásit spam 1 / 1 odpovědětodpovědět
                       
Nadpis:
Antispam: Komu se občas házejí perly?
Příspěvek bude publikován pod identitou   anonym.
  • Administrátoři si vyhrazují právo komentáře upravovat či mazat bez udání důvodu.
    Mazány budou zejména komentáře obsahující vulgarity nebo porušující pravidla publikování.
  • Pokud nejste zaregistrováni, Vaše IP adresa bude zveřejněna. Pokud s tímto nesouhlasíte, příspěvek neodesílejte.

přihlásit pomocí externího účtu

přihlásit pomocí jména a hesla

Uživatel:  
Heslo:  

zapomenuté heslo

 

založit nový uživatelský účet

zaregistrujte se

 
zavřít

Nahlásit spam

Opravdu chcete tento příspěvek nahlásit pro porušování pravidel fóra?

Nahlásit Zrušit

Chyba

zavřít

feedback