Toon posts:

C# SQLite:Concurrency violation Delete Command op 1e row

Pagina: 1
Acties:
  • 334 views

Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
ik heb volgende C# code voor een Savebutton, die de aangepaste (inserted/deleted/updated) rijen uit een datagridview moet bewaren in een ingeladen datatable:

C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
       private void SaveButton_Click(object sender, EventArgs e)
        {
            string currenttable = tableComboBox.Text;

            if (!(String.IsNullOrEmpty(currenttable)) && TableExists(currenttable, sqlConnect))
            {
                if (sqlConnect != null && sqlConnect.State == ConnectionState.Closed)
                {
                    //open database if closed
                    sqlConnect.Open();
                }
        
                SQLiteCommandBuilder SQLiteCommandBuilder = new SQLiteCommandBuilder(sqliteAdapter);

                try
                {
                    SQLiteCommandBuilder.GetInsertCommand();
                    SQLiteCommandBuilder.GetUpdateCommand();
                    SQLiteCommandBuilder.GetDeleteCommand();

                    //update dataset
                    sqliteAdapter.Update(dataTable); //Sqliteadapter is geldig, werd eerder in code al geinstanced
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }

                if (sqlConnect != null && sqlConnect.State == ConnectionState.Open)
                {
                    //close database if opened
                    sqlConnect.Close();
                }
            }
        }


Wanneer ik manueel, via de GUI dus, bepaalde rijen/cellen in de datagrid aanpas, toevoeg, verwijder,.. dan kan ik deze wijzigingen perfect opslaan met deze savebutton, zolang de eerste rij er niet tussen zit.

Anders krijg ik de error:
"Concurrency violation: the DeleteCommand affected 0 of the expected 1 records"
en worden de aanpassingen niet bewaard.

Er is een auto-incrementing primary key ingesteld voor de database.
Heb al heel veel over dit type fout over gelezen (zoals op http://www.codeproject.co...currency-violation-the-De ), maar vind niet de correcte oplossing.
Tevens wil ik mijn code zo simpel mogelijk houden.

Hoe zou ik dit kunnen in orde krijgen?

Acties:
  • 0 Henk 'm!

  • Juup
  • Registratie: Februari 2000
  • Niet online
1. Zet je code in [ code] tags
2. Zet hier je `show create table` sql neer van de betreffende tabellen
3. Welke sql wordt er uitgevoerd bij de actie die die error geeft?

Een wappie is iemand die gevallen is voor de (jarenlange) Russische desinformatiecampagnes.
Wantrouwen en confirmation bias doen de rest.


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
code tags: heb geen idee hoe je dat hier doet? :p

ik weet van geen "show create table sql", ik heb via sqliteadmin de sqlite file volledig naar wens ingesteld,
verwijs mijn connection string gewoon naar deze file.

er wordt GEEN sql uitgevoerd, misschien is dat een deel van het probleem. ik wil enkel de manuele aanpassingen die ik via de datagrid doe, terug laten koppelen naar de database + daar opslaan, en dit lukt perfect behalve voor de eerste rij, heel vreemd...

Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
heb eens de kolom ID met auto increment weggehaald, maar dit maakt geen verschil, dus hier heeft al niet mee te maken...

Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
tis me al deels zelf gelukt, de clue was dat er natuurlijk achter het Delete key event ook nog een achterliggend SQL statement moet opgesteld en uitgevoerd worden.

Ik dacht dat datagridview object zo intelligent was om de updates zelf terug te koppelen de database, maar blijkbaar is dit niet zo.

voor wie het interesseert, oplossing betrof aanpassingen op verschillende plaatsen:

C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
//registreer key event handler voor de delete toets wanneer de form opstart:
            this.FormDataGridView.KeyDown += new KeyEventHandler(FormDataGridView_KeyDown); 

//hang een nieuwe method aan deze handler
        private void FormDataGridView_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Delete)
            {
                FormDataGridView_RemoveRow(sender, e);
            }
        }

//zet in de method het delete sql statement, die via de selected-row-value van cell met index 0 achterhaalt welke de primary key van de row is, en verwijder deze row eerst uit database en daarna uit de datagridview

     private void FormDataGridView_RemoveRow(object sender, EventArgs e)
        {
            string currenttable = tableComboBox.Text;

            foreach (DataGridViewRow selectedrow in FormDataGridView.SelectedRows)
            {
                if (selectedrow.Selected)
                {
                    //Reset rowcount value
                    int rowcount = 0;

                    if (sqlConnect != null && sqlConnect.State == ConnectionState.Closed)
                    {
                        //open database if closed
                        sqlConnect.Open();
                    }

                    sqlquery = "SELECT Count(*) FROM '" + currenttable + "' WHERE ID = '" + selectedrow.Cells[0].Value.ToString() + "';";
                    sqliteCommand.CommandText = sqlquery;
                    rowcount = Convert.ToInt32(sqliteCommand.ExecuteScalar());

                    if (rowcount > 0)
                    {

                        sqlstatement = "DELETE FROM '" + currenttable + "' WHERE ID= '" + selectedrow.Cells[0].Value.ToString() + "';";

                        //open transaction mode
                        using (var transaction = sqlConnect.BeginTransaction())
                        {
                            try
                            {
                                // prepare command
                                sqliteCommand = new SQLiteCommand(sqlstatement, sqlConnect);

                                //run command
                                sqliteCommand.ExecuteNonQuery();

                                //commit changes
                                transaction.Commit();

                                //verwijder van de datagridview
                                FormDataGridView.Rows.RemoveAt(selectedrow.Cells[0].RowIndex);
                            }
                            catch (Exception ex)
                            {
                                MessageBox.Show(ex.Message);
                                try
                                {
                                    transaction.Rollback();
                                }
                                catch { MessageBox.Show("An error occurred while trying to rollback database!"); }
                            }
                        }

                        if (sqlConnect != null && sqlConnect.State == ConnectionState.Open)
                        {
                            //close database if opened
                            sqlConnect.Close();
                        }

                        //update datagridview
                        queryTable_Click(null, null);
                    } 
                }
            }
        }


nu zit ik nog met het probleem dat de save-button overbodig is, aangezien ik de transactie al commit in de removerow method zelf...

Ik zal nog moeten een cancel mogelijkheid moeten inbouwen die een rollback in gang steekt wanneer ik de form afsluit zonder op save te klikken bijvoorbeeld, of kan dit eenvoudiger?

Acties:
  • 0 Henk 'm!

  • Mavamaarten
  • Registratie: September 2009
  • Laatst online: 20:56

Mavamaarten

Omdat het kan!

Zoek dan even op hoe de code tags werken als je niet weet hoe dat werkt, het is erg vervelend om op deze manier je code te lezen.

Hint: code tags gebruik je hier zo:
code:
1
[code="C#"] // Jouw code hier [/code]

[ Voor 15% gewijzigd door Mavamaarten op 29-11-2015 13:24 ]

Android developer & dürüm-liefhebber


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
bij deze gebeurd, thx voor de tip :)

Acties:
  • 0 Henk 'm!

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 09-09 13:58

NMe

Quia Ego Sic Dico.

Verwijderd schreef op zaterdag 28 november 2015 @ 22:04:
code tags: heb geen idee hoe je dat hier doet? :p
Dan is het misschien een goed idee om de FAQ en beleidstopics eens door te lezen voor je een topic opent? Ik zie in het beleidstopic toch echt een kopje "Hoe post je code?"

Verder vind ik als ik op Google je foutmelding letterlijk overtik talloze resultaten die het probleem omschrijven en oplossen, waar je vervolgens niets over zegt in je topicstart? Welke van die oplossingen heb je geprobeerd? Wat werkte er niet aan? Oftewel: De Quickstart.

Verder is het niet gewenst om als je als laatste gereageerd hebt binnen 24 uur nogmaals te reageren in je eigen topic. Dat zogenaamde schoppen van je topic om het extra onder de aandacht te brengen voegt niets toe. De volgende melding staat er niet voor niets:

Afbeeldingslocatie: http://tweakers.net/ext/f/rViZSDpQ5n2TpYCcyrDz83Jf/full.png


Mocht je nog steeds problemen hebben, open dan gerust een topic dat aan de quickstart voldoet. Op deze manier zijn we in elk geval niet getrouwd. ;)

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.

Pagina: 1

Dit topic is gesloten.