[C#] Laatste ID selecteren

Pagina: 1
Acties:

Acties:
  • 0 Henk 'm!

  • tha_crazy
  • Registratie: Maart 2007
  • Laatst online: 20:59
Hey mensen, ik zit met een probleempje.
De titel zegt het al, de laatste ID.
Ik werk met een Datagrid om waardes toe te voegen/verwijderen/wijzigen.
Echter als ik een waarde toevoeg en ik de laatste ID wil selecteren krjig ik hier continu de error "Specified cast is not valid."

Ik gebruik de volgende reeksen van codes

Kijken of er geupdate moet worden of geinsert. Dit werkt.
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
        private void dataGridView1_RowValidated(object sender, DataGridViewCellEventArgs e)
        {
            if (_allow == true)
            {

                if (dataGridView1.Rows[e.RowIndex].IsNewRow == true) return;
                if (dataGridView1.Rows[e.RowIndex].Cells[1].Value == null || dataGridView1.Rows[e.RowIndex].Cells[2].Value == null || dataGridView1.Rows[e.RowIndex].Cells[3].Value == null || dataGridView1.Rows[e.RowIndex].Cells[4].Value == null)
                    return;

                DataGridViewRow row = dataGridView1.Rows[e.RowIndex];

                if (row.Cells[0].Value == null || Convert.ToInt32(row.Cells[0].Value) == 0)
                {
                    insert(row);
                }
                else
                {
                    update(row);
                }
            }
        }


De insert, deze werkt ook nog.
code:
1
2
3
4
5
6
7
8
9
        private void insert(DataGridViewRow e)
        {
            string qryinsert = "INSERT INTO infra_software (soft_name, soft_manufacturer, soft_date, soft_license) VALUES ('" + e.Cells[1].Value.ToString() + "','" + e.Cells[2].Value.ToString() + "','" + e.Cells[3].Value.ToString() + "','" + e.Cells[4].Value.ToString() + "')";
            SqlCommand execinsert = new SqlCommand(qryinsert);
            execinsert.Connection = Classes.connector.mycon;
            execinsert.ExecuteNonQuery();
            e.Cells[0].Value = GetLastInsertedID();
            
        }

Zoals je ziet gaat deze naar een andere functie, GetLastInsertedID();
Deze selecteert de laatste ID op de volgende manier zoals ik al op het internet gevonden heb en uit eedere scripts.

De code van de select voor de laatste ID
code:
1
2
3
4
5
6
7
8
9
        private int GetLastInsertedID()
        {
            string qryLastValue = "select @@IDENTITY as ID";
            SqlCommand myOdbcCommand = new SqlCommand(qryLastValue);
            myOdbcCommand.Connection = Classes.connector.mycon;
            SqlDataReader aReader = myOdbcCommand.ExecuteReader();
            aReader.Read();
            return (int)aReader.GetValue(0);
        }


Bij de return geeft hij de error van "Specified cast is not valid"
Ik heb ook al geprobeert de datagrid te refreshen zoals ik bij een andere functie gebruik maar dit wil echter ook niet werken.
Heeft iemand een idee waar het aan kan liggen ?

Acties:
  • 0 Henk 'm!

  • bigbeng
  • Registratie: Augustus 2000
  • Laatst online: 26-11-2021
Heb je de debugger al eens gebruikt? Dan kun je runtime opvrangen welke waarde aReader.GetValue(0) heeft, wat het type is en meer van dat soort zaken. Gewoon een breakpoint zetten op de gewraakte regel en eens goed rondkijken.

Mijn eerste gok is dat je een database integer niet zomaar naar een int kan casten. Gebruik daarvoor de Convert die je elders in je code ook al gebruikt.

Acties:
  • 0 Henk 'm!

  • Niemand_Anders
  • Registratie: Juli 2006
  • Laatst online: 09-07-2024

Niemand_Anders

Dat was ik niet..

Het gebruik van @@IDENTITY is eigenlijk best gevaarlijk. SCOPE_IDENTITY() geeft altijd het toegevoegde ID op basis van je connectie terug.
Replication may affect the @@IDENTITY value, since it is used within the replication triggers and stored procedures. @@IDENTITY is not a reliable indicator of the most recent user-created identity if the column is part of a replication article. You can use the SCOPE_IDENTITY() function syntax instead of @@IDENTITY. For more information, see SCOPE_IDENTITY (Transact-SQL)
Maar heb je er weleens bij stil gestaan dat je niet controleert of ExecuteNonQuery() ook aangeeft dat er records zijn gewijzigd (inserted, updated or deleted)? Je doet wel wel een Read() maar ook daar doe je geen controle of deze wel succesvol is.

En vervolgens doe je een GetValue(0). Waarom je daar geen GetInt32(0) gebruikt snap ik ook niet helemaal.

If it isn't broken, fix it until it is..


Acties:
  • 0 Henk 'm!

  • whoami
  • Registratie: December 2000
  • Laatst online: 19:58
Debuggen, zou ik zeggen ... Check of je reader wel rows bevat in die method, kijk of er geen NULL gereturned wordt (als je select @@identity op een andere connectie uitvoert, zal dat zeker zo zijn).

Wat returned die 'connector.mycon' precies ? Is dat altijd een nieuwe connectie naar de DB ?

Trouwens, je kan ook ExecuteScalar gebruiken in je GetLastInsertedId method ipv een Reader te gaan instantieren (die je trouwens vergeet te sluiten/vrij te geven).

https://fgheysels.github.io/


Acties:
  • 0 Henk 'm!

  • tha_crazy
  • Registratie: Maart 2007
  • Laatst online: 20:59
bigbeng schreef op maandag 24 november 2008 @ 11:52:
Heb je de debugger al eens gebruikt? Dan kun je runtime opvrangen welke waarde aReader.GetValue(0) heeft, wat het type is en meer van dat soort zaken. Gewoon een breakpoint zetten op de gewraakte regel en eens goed rondkijken.

Mijn eerste gok is dat je een database integer niet zomaar naar een int kan casten. Gebruik daarvoor de Convert die je elders in je code ook al gebruikt.
Die convert deed het hem inderdaad.
Maar het rare is dat ik deze code al eens bij een AccessDB heb gebruikt en hij toen geen problemen gaf.
maar hij werkt nu.
Bedankt :)