2016-11-02 1 views
1

J'ai une entité simple:Xamarin Sqlite Insérer ne retourne pas la dernière id clé primaire

[Table("History")] 
public class History 
{ 
    [PrimaryKey, AutoIncrement, Column("_id")] 
    public int Id { get; set; } 

    [Indexed(Name = "IDX_History", Order = 1, Unique = true)] 
    public int Prefix { get; set; } 

    [Indexed(Name = "IDX_History", Order = 2, Unique = true)] 
    public int Stem { get; set; } 

    [Indexed(Name = "IDX_History", Order = 3, Unique = true)] 
    public int Suffix { get; set; } 

    [Indexed(Name = "IDX_Favourite")] 
    public bool IsFavourite { get; set; } 

    public DateTime LastViewed { get; set; } = DateTime.Now; 
} 

Je suis en train de faire un insert si son nouveau ou d'obtenir le dernier id Inséré si elle existe déjà:

public static int SaveSolutionToHistory(Solution sol) 
{ 
    lock (_db) 
    { 
     var existingHistory = _db.Table<History>().FirstOrDefault(h => h.Prefix == sol.Prefix.Id 
      && h.Stem == sol.Stem.Id 
      && h.Suffix == sol.Suffix.Id); 

     if (existingHistory != null) 
     { 
      existingHistory.LastViewed = DateTime.Now; 
      _db.Update(existingHistory); 
      return existingHistory.Id; 
     } 

     _db.Insert(new History 
     { 
      Prefix = sol.Prefix.Id, 
      Stem = sol.Stem.Id, 
      Suffix = sol.Suffix.Id 
     }); 

     return _db.ExecuteScalar<int>("SELECT last_insert_rowid()"); 
    } 
} 

la partie supérieure fonctionne très bien à retourner une carte d'identité pour les entrées existantes, mais pour une raison quelconque le code d'insertion renvoie toujours quand il doit retourner le dernier id autoincrement primaire inséré (comme mentionné dans le commentaire XML méthodes):

 _db.Insert(new History 
    { 
     Prefix = sol.Prefix.Id, 
     Stem = sol.Stem.Id, 
     Suffix = sol.Suffix.Id 
    }); 

Et cela renvoie l'ID correct:

return _db.ExecuteScalar<int>("SELECT last_insert_rowid()"); 

Il me semble inefficace pour faire deux coups comme celui-ci ou de le faire comme non fortement typé. Y at-il une raison pour laquelle le _db.Insert ne renvoie pas l'ID correct? J'utilise VS 2015, avec HAXM et Marshmallow x86_64 Image API Google.

Répondre

2

J'ai eu le même problème, vient de trouver la réponse here, le commentaire complet xml est:

// 
// Summary: 
//  /// Inserts the given object and retrieves its /// auto incremented primary key 
//  if it has one. /// 
// 
// Parameters: 
// obj: 
//  /// The object to insert. /// 
// 
// Returns: 
//  /// The number of rows added to the table. /// 

Ce que le résumé entend par « extrait » est qu'il met à jour la valeur du champ PK dans l'objet que vous lui avez passé, si vous voulez le dernier id inséré, vous pouvez l'utiliser

0

Vous pouvez insérer des lignes dans la base de données en utilisant Insérer. Si la table contient une clé primaire auto-incrémentée, la valeur de cette clé sera à votre disposition après l'insertion:

public static void AddStock (SQLiteConnection db, string symbol) { 
    var s = new Stock { Symbol = symbol }; 
    db.Insert (s); 
    Console.WriteLine ("{0} == {1}", s.Symbol, s.Id); 
} 

C'est dire que ID sera disponible dans le champ d'objet Id.

https://components.xamarin.com/gettingstarted/sqlite-net