2010-12-02 15 views
17

J'ai un problème simple avec un pas si simple solution ... Je suis actuellement des données insérez dans une base de données comme ceci:Obtenir la dernière insertion ID avec SQLite.NET en C#

   kompenzacijeDataSet.KompenzacijeRow kompenzacija = kompenzacijeDataSet.Kompenzacije.NewKompenzacijeRow(); 
       kompenzacija.Datum = DateTime.Now; 
       kompenzacija.PodjetjeID = stranka.id; 
       kompenzacija.Znesek = Decimal.Parse(tbZnesek.Text); 

       kompenzacijeDataSet.Kompenzacije.Rows.Add(kompenzacija); 

       kompenzacijeDataSetTableAdapters.KompenzacijeTableAdapter kompTA = new kompenzacijeDataSetTableAdapters.KompenzacijeTableAdapter(); 
       kompTA.Update(this.kompenzacijeDataSet.Kompenzacije); 

       this.currentKompenzacijaID = LastInsertID(kompTA.Connection); 

La dernière ligne est important. Pourquoi est-ce que je fournis une connexion? Eh bien, il existe une fonction SQLite appelée last_insert_rowid() que vous pouvez appeler et obtenir le dernier ID d'insertion. Le problème est qu'il est lié à une connexion et .NET semble réouvrir et fermer les connexions pour chaque opération de jeu de données. Je pensais que l'obtention de la connexion à partir d'un adaptateur de table changerait les choses. Mais ce n'est pas le cas.

Quelqu'un pourrait-il résoudre ce problème? Peut-être où obtenir une connexion constante de? Ou peut-être quelque chose de plus élégant?

Merci.

EDIT:

Ceci est également un problème avec les transactions, je besoin de la même connexion si je voudrais utiliser des transactions, de sorte que c'est aussi un problème ...

Répondre

43
select last_insert_rowid(); 

Et vous devra l'exécuter en tant que requête scalaire.

string sql = @"select last_insert_rowid()"; 
long lastId = (long)command.ExecuteScalar(sql); // Need to type-cast since `ExecuteScalar` returns an object. 
+2

rowid doit être coulé à Int64: 'var result = (Int64) command.ExecuteScalar (SQL);' ' – Johnny

+7

Le type de valeur de long' est déjà un' Int64'. –

+0

J'ai trouvé que cette réponse ne fonctionne pas. La réponse suivante (par Alex Smith) fonctionne. – ttom

7

last_insert_rowid() fait partie de la solution. Il renvoie un numéro de ligne, pas l'ID réel.

cmd = CNN.CreateCommand(); 
cmd.CommandText = "SELECT last_insert_rowid()"; 
object i = cmd.ExecuteScalar(); 

cmd.CommandText = "SELECT " + ID_Name + " FROM " + TableName + " WHERE rowid=" + i.ToString(); 
i = cmd.ExecuteScalar(); 
41

en utilisant C# (.NET 4.0) avec SQLite, la classe SQLiteConnection a une propriété LastInsertRowId qui correspond à l'entier clé primaire de l'élément le plus récemment inséré (ou mis à jour).

L'identificateur de ligne est renvoyé si la table ne possède pas de clé de type entier (dans ce cas, la ligne rowID est automatiquement créée).

Voir https://www.sqlite.org/c3ref/last_insert_rowid.html pour plus d'informations.

En ce qui concerne l'encapsulation de plusieurs commandes dans une seule transaction, toutes les commandes entrées après le début de la transaction et avant sa validation font partie d'une transaction.

long rowID; 
using (SQLiteConnection con = new SQLiteConnection([datasource]) 
{ 
    SQLiteTransaction transaction = null; 
    transaction = con.BeginTransaction(); 

    ... [execute insert statement] 

    rowID = con.LastInsertRowId; 

    transaction.Commit() 
} 
+3

Cela nécessite plus de votes. C'est la voie à suivre pour de nouvelles applications autant que je vois. –

+0

Cette réponse fonctionne. L'autre réponse ne le fait pas. – ttom

0

Le objet SQLiteConnection a une propriété pour cela, il n'y a donc pas besoin de requête supplémentaire. Après INSÉRER vous juste mon utilisation LastInsertRowId propriété de votre objet SQLiteConnection qui a été utilisé pour la commande INSERT. Type de LastInsertRowId La propriété est Int64. Bien sûr, comme vous l'avez déjà fait, pour que l'incrémentation automatique fonctionne, la clé primaire de la table doit être AUTOINCREMENT, ce qui constitue un autre sujet.

0
database = new SQLiteConnection(databasePath); 

    public int GetLastInsertId() 
    { 
     return (int)SQLite3.LastInsertRowid(database.Handle); 
    } 
+0

désolé, son travail pour sqlite-net-pcl –

+0

gentil, merci pour cela: P –