2013-03-18 11 views
6

SQLite z WP8 doprowadza mnie do szału. :(WP8/C#/SQLite: pobierz ostatni wstawiony identyfikator?

Wszystko co chcę zrobić, to pobrać wartość ostatniego wstawiony id ...

mam:

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;} 
} 

Cóż, ani wykorzystywane SQLiteConnection obiektu ani jego Table<ShoppingItem> wydają się zawierać odpowiedni element, który zawiera ostatni identyfikator

Więc starałem się zrobić.

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

Ale ta funkcja zawsze zwraca 0. :( Ale kiedy czytam wszystkie wpisy ShoppingItem, ich identyfikatory mają wartości = 0.

Więc moje pytanie brzmi: Jak mogę retreive ostatni zapisany identyfikator

PS: Zmiana zapytania SQL do SELECT last_insert_rowid() FROM ShoppingItem; dało ten sam wynik

PPS. Rozwiązania takie jak Getting the Last Insert ID with SQLite.NET in C# nie kompiluje, najwyraźniej jest to starsza wersja SQLite używany, z zupełnie innej API

+0

jest db.ExecuteScalar ("SELECT last_insert_rowid()"); pracujący? (Bez, na końcu zapytania) – Joel

+0

nie, ten sam wynik z średnikiem lub bez średnika :( –

+0

Polecam wybrać inną nazwę dla twojej kolumny pk "Id" .Nie wiem czy Id jest czymś w rodzaju wewnętrzne słowo kluczowe, ale domyślam się, – Joel

Odpowiedz

11

Twój SELECT last_insert_rowid() wywołanie nie działa, ponieważ używasz go w połączeniu z bazą danych inny.

W każdym razie, należy po prostu odczytać identyfikator z włożonej ShoppingItem obiektu, na przykład:

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

ah, OK, nowe połączenie to prawdopodobnie Ale jak mogę odczytać identyfikator obiektu, który właśnie włożyłem? –

+0

spojrzeć na moje zaktualizowane rozwiązanie (Metoda: insertExpenseItem2) kwerendy jest enkapsulacji do transakcji i używa zatem tego samego połączenia z bazą danych. – Joel

+0

dziękuję bardzo.Niefortunnie nie znalazłem żadnej dobrej dokumentacji "nowego" SQLite. –

0

to jest to, co zrobić, aby pobrać identyfikator ostatniego elementu wstawionego Podany fragment kodu działa w mojej Wi ndows 8 Aplikacja używająca 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; 
    } 
} 

właściwości ID w klasie FinancialListBoxItem wygląda następująco:

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); 
      } 
     } 
} 

Polecam, aby wybrać inną nazwę dla swojej kolumnie pk „id”. Nie wiem, czy Id jest czymś w rodzaju wewnętrznego słowa kluczowego. EDIT: Dobra to nie jest słowo kluczowe SQLite ale id nie jest prawidłowa nazwa zresztą (Źródło: 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 
} 
Powiązane problemy