Come recuperare l’ultimo ID autoincrementato da una tabella SQLite?

Ho una tabella Messaggi con colonne ID (chiave primaria, autoincremento) e Contenuto (testo).
Ho una tabella Utenti con nome utente colonne (chiave primaria, testo) e Hash.
Un messaggio viene inviato da un mittente (utente) a molti destinatari (utente) e un destinatario (utente) può avere molti messaggi.
Ho creato una tabella Messages_Recipients con due colonne: MessageID (che fa riferimento alla colonna ID della tabella Messaggi e Destinatario (facendo riferimento alla colonna nome utente nella tabella Utenti) .Questa tabella rappresenta la relazione molti a molti tra destinatari e messaggi.

Quindi, la domanda che ho è questa. L’ID di un nuovo messaggio verrà creato dopo che è stato memorizzato nel database. Ma come posso mantenere un riferimento al MessageRow che ho appena aggiunto per recuperare questo nuovo MessageID?
Posso sempre cercare nel database l’ultima riga aggiunta, naturalmente, ma questo potrebbe restituire una riga diversa in un ambiente con multithreading?

EDIT: Come ho capito per SQLite è ansible utilizzare il SELECT last_insert_rowid() . Ma come posso chiamare questa dichiarazione da ADO.Net?

Il mio codice di persistenza (messaggi e messaggiRecipients are DataTables):

 public void Persist(Message message) { pm_databaseDataSet.MessagesRow messagerow; messagerow=messages.AddMessagesRow(message.Sender, message.TimeSent.ToFileTime(), message.Content, message.TimeCreated.ToFileTime()); UpdateMessages(); var x = messagerow;//I hoped the messagerow would hold a //reference to the new row in the Messages table, but it does not. foreach (var recipient in message.Recipients) { var row = messagesRecipients.NewMessages_RecipientsRow(); row.Recipient = recipient; //row.MessageID= How do I find this?? messagesRecipients.AddMessages_RecipientsRow(row); UpdateMessagesRecipients();//method not shown } } private void UpdateMessages() { messagesAdapter.Update(messages); messagesAdapter.Fill(messages); } 

Con SQL Server dovresti selezionare SCOPE_IDENTITY () per ottenere l’ultimo valore di id quadro per il processo corrente.

Con SQlite, sembrerebbe un autoincremento che avresti fatto

 SELECT last_insert_rowid() 

subito dopo il tuo inserimento.

http://www.mail-archive.com/[email protected]/msg09429.html

In risposta al tuo commento per ottenere questo valore vorresti usare il codice SQL o OleDb come:

 using (SqlConnection conn = new SqlConnection(connString)) { string sql = "SELECT last_insert_rowid()"; SqlCommand cmd = new SqlCommand(sql, conn); conn.Open(); int lastID = (Int32) cmd.ExecuteScalar(); } 

Un’altra opzione è quella di esaminare la tabella di sistema sqlite_sequence . Il tuo database sqlite avrà automaticamente quella tabella se hai creato una tabella con la chiave primaria autoincrement. Questa tabella è per sqlite per tenere traccia del campo di autoincremento in modo che non ripeta la chiave primaria anche dopo aver eliminato alcune righe o dopo che alcuni inserimenti non sono riusciti (leggi di più su questo qui http://www.sqlite.org/autoinc .html ).

Quindi con questa tabella c’è il vantaggio che puoi scoprire la chiave primaria del tuo nuovo object inserito anche dopo aver inserito qualcos’altro (in altre tabelle, ovviamente!). Dopo esserti assicurato che il tuo inserimento abbia successo (altrimenti otterrai un numero falso), devi semplicemente fare:

 select seq from sqlite_sequence where name="table_name" 

Ho avuto problemi con l’utilizzo di SELECT last_insert_rowid() in un ambiente con multithreading. Se un altro thread si inserisce in un’altra tabella con un autoinc, last_insert_rowid restituirà il valore autoinc dalla nuova tabella.

Ecco dove si afferma che nella doco:

Se un thread separato esegue un nuovo INSERT sulla stessa connessione al database mentre la funzione sqlite3_last_insert_rowid () è in esecuzione e quindi modifica l’ultimo rowid di inserimento, il valore restituito da sqlite3_last_insert_rowid () è imprevedibile e potrebbe non corrispondere al vecchio o al nuovo ultimo inserire il rowid.

Questo è da sqlite.org doco

Esempio di codice dalla soluzione @polyglot

 SQLiteCommand sql_cmd; sql_cmd.CommandText = "select seq from sqlite_sequence where name='myTable'; "; int newId = Convert.ToInt32( sql_cmd.ExecuteScalar( ) ); 

Secondo Android Sqlite ottieni l’ultimo ID della riga di inserimento c’è un’altra query:

 SELECT rowid from your_table_name order by ROWID DESC limit 1