2013-03-18 13 views
6

SQLite mit WP8 macht mich verrückt. :(WP8/C#/SQLite: Letzte ID erhalten?

Alles, was ich tun möchte, ist der Wert der zuletzt eingefügte ID abzurufen ...

Ich habe:

class ShoppingItem 
{ 
    [SQLite.PrimaryKey, SQLite.AutoIncrement] 
    public int Id {get; set;} 
    public string Name {get; set;} 
    public string Shop {get; set;} 
    public bool isActive {get; set;} 
} 

Nun, weder das verwendete SQLiteConnection Objekt noch seine Table<ShoppingItem> scheint ein geeignetes Mitglied zu enthalten, das die letzte ID enthält

So zu tun, habe ich versucht.

private int GetLastInsertedRowID() 
{ 
    int Result = -1; 
    using (var db = new SQLiteConnection(m_DatabasePath)) { 
    Result = db.ExecuteScalar<int>("SELECT last_insert_rowid();"); 
    } 
    return Result; 
} 

Diese Funktion gibt jedoch immer 0 zurück. :( Aber wenn ich alle Einträge von ShoppingItem lesen, haben ihre IDs Werte = 0

Also meine Frage ist: Wie kann ich die letzte Eingabe id retreive

PS:? Ändern der SQL-Abfrage SELECT last_insert_rowid() FROM ShoppingItem; das gleiche Ergebnis gab

PPS:. Lösungen wie Getting the Last Insert ID with SQLite.NET in C# kompilieren nicht, anscheinend gibt es eine ältere SQLite-Version verwendet wird, mit einer ganz anderen API

+0

ist db.ExecuteScalar ("SELECT last_insert_rowid()"); Arbeiten? (Ohne; am Ende der Abfrage) – Joel

+0

nein, das gleiche Ergebnis mit oder ohne Semikolon :( –

+0

Ich würde empfehlen, dass Sie einen anderen Namen für Ihre PK-Spalte "Id" wählen. Ich weiß nicht, ob Id so etwas wie ein ist Internes Schlüsselwort. Aber ich rate nur hier. – Joel

Antwort

11

Ihr SELECT last_insert_rowid() Aufruf funktioniert nicht, weil Sie es in einer Verbindung verschiedenen Datenbank ausgeführt werden.

Auf jeden Fall sollten Sie lesen gerade die ID aus der eingesetzten ShoppingItem Objekt, wie folgt aus:

var si = new ShoppingItem() { 
    Name = anItem, 
    Shop = aShop, 
    isActive = aIsActive, 
}; 
db.Insert(si); 
return si.Id; 
+0

ah, OK, die neue Verbindung ist das prob. Aber wie lese ich die Identifikation vom Objekt, das ich gerade einfügte? –

+0

Schauen Sie sich meine aktualisierte Lösung an (Methode: insertExpenseItem2) Die Abfrage ist in eine Transaktion eingekapselt und verwendet daher die gleiche Datenbankverbindung – Joel

+0

vielen Dank Leider habe ich keine gute Dokumentation der "neuen" SQLite gefunden. –

0

Dies ist, was ich die ID des zuletzt eingefügte Element abzurufen tun Das mitgelieferte Code-Snippet funktioniert in meinem Wi ndows 8 App mit SQLite 3.7.XX (SQLite).

public class ExpenseDataMapper 
    { 
     SQLiteConnection connection; 

     /// <summary> 
     /// Constructor 
     /// </summary> 
     public ExpenseDataMapper() 
     { 
      connection = new SQLiteConnection(StaticResources.DATABASE_PATH_NAME); 

      connection.CreateTable<FinancialListBoxExpenseItem>(); 
     } 

     /// <summary> 
     /// Method #1: Inserts an FinancialListBoxExpenseItem into Database 
     /// </summary> 
     /// <param name="item"></param> 
     /// <returns>Primary key of inserted item</returns> 
     public int insertExpenseItem(FinancialListBoxExpenseItem item) 
     { 
      int primaryKey = 0; 
      connection.RunInTransaction(() => 
          { 
           connection.Insert(item); 
           primaryKey = item.expenseID; 
          }); 

      return primaryKey; 
     } 

    /// <summary> 
    /// Method #2: Inserts an FinancialListBoxExpenseItem into Database 
    /// </summary> 
    /// <param name="item"></param> 
    /// <returns>Primary key of inserted item</returns> 
    public int insertExpenseItem2(FinancialListBoxExpenseItem item) 
    { 
     int primaryKey = 0; 
     connection.RunInTransaction(() => 
         { 
          connection.Insert(item); 
          primaryKey = connection.ExecuteScalar<int>("SELECT last_insert_rowid()"); 
         }); 

     return primaryKey; 
    } 
} 

Die ID-Eigenschaft in der FinancialListBoxItem Klasse sieht wie folgt aus:

public class FinancialListBoxExpenseItem : Money.Common.BindableBase 
    { 

     private int _expenseID = 0; 
     [AutoIncrement, PrimaryKey] 
     public int expenseID 
     { 
      get 
      { 
       return _expenseID; 
      } 

      set 
      { 
       this.SetProperty<int>(ref _expenseID, value); 
      } 
     } 
} 

Ich würde empfehlen, dass Sie einen anderen Namen für die pk Spalte 'Id' zu wählen. Ich weiß nicht, ob Id so etwas wie ein internes Keyword ist. EDIT: Okay es ist kein SQLite Schlüsselwort aber id ist kein Eigenname sowieso (Quelle: SQLite Keywords)

-1
public List<int[]> CreateSymbolByName(string SymbolName, bool AcceptDuplicates) 
    { 
     if (! AcceptDuplicates) // check if "AcceptDuplicates" flag is set 
     { 
      List<int[]> ExistentSymbols = GetSymbolsByName(SymbolName, 0, 10); // create a list of int arrays with existent records 
      if (ExistentSymbols.Count > 0) return ExistentSymbols; //(1) return existent records because creation of duplicates is not allowed 
     } 
     List<int[]> ResultedSymbols = new List<int[]>(); // prepare a empty list 
     int[] symbolPosition = { 0, 0, 0, 0 }; // prepare a neutral position for the new symbol 
     try // If SQL will fail, the code will continue with catch statement 
     { 
      //DEFAULT und NULL sind nicht als explizite Identitätswerte zulässig 
      string commandString = "INSERT INTO [simbs] ([En]) OUTPUT INSERTED.ID VALUES ('" + SymbolName + "') "; // Insert in table "simbs" on column "En" the value stored by variable "SymbolName" 
      SqlCommand mySqlCommand = new SqlCommand(commandString, SqlServerConnection); // initialize the query environment 
       SqlDataReader myReader = mySqlCommand.ExecuteReader(); // last inserted ID is recieved as any resultset on the first column of the first row 
       int LastInsertedId = 0; // this value will be changed if insertion suceede 
       while (myReader.Read()) // read from resultset 
       { 
        if (myReader.GetInt32(0) > -1) 
        { 
         int[] symbolID = new int[] { 0, 0, 0, 0 }; 
         LastInsertedId = myReader.GetInt32(0); // (2) GET LAST INSERTED ID 
         symbolID[0] = LastInsertedId ; // Use of last inserted id 
         if (symbolID[0] != 0 || symbolID[1] != 0) // if last inserted id succeded 
         { 
          ResultedSymbols.Add(symbolID); 
         } 
        } 
       } 
       myReader.Close(); 
      if (SqlTrace) SQLView.Log(mySqlCommand.CommandText); // Log the text of the command 
      if (LastInsertedId > 0) // if insertion of the new row in the table was successful 
      { 
       string commandString2 = "UPDATE [simbs] SET [IR] = [ID] WHERE [ID] = " + LastInsertedId + " ;"; // update the table by giving to another row the value of the last inserted id 
       SqlCommand mySqlCommand2 = new SqlCommand(commandString2, SqlServerConnection); 
       mySqlCommand2.ExecuteNonQuery(); 
       symbolPosition[0] = LastInsertedId; // mark the position of the new inserted symbol 
       ResultedSymbols.Add(symbolPosition); // add the new record to the results collection 
      } 
     } 
     catch (SqlException retrieveSymbolIndexException) // this is executed only if there were errors in the try block 
     { 
      Console.WriteLine("Error: {0}", retrieveSymbolIndexException.ToString()); // user is informed about the error 
     } 

    CreateSymbolTable(LastInsertedId); //(3) // Create new table based on the last inserted id 
    if (MyResultsTrace) SQLView.LogResult(LastInsertedId); // log the action 
    return ResultedSymbols; // return the list containing this new record 
}