2013-03-18 3 views
6

SQLite с WP8 сводит меня с ума. :(WP8/C#/SQLite: получить последний вставленный идентификатор?

Все, что я хочу сделать, это получить значение последнего вставленного ид ...

У меня нет:

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

Ну, ни использовал SQLiteConnection объект, ни его Table<ShoppingItem> кажется, содержит соответствующий элемент, содержащий последний ID

Так что я пытался сделать:.

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

Но эта функция всегда возвращает 0. :( Но когда я прочитал все записи ShoppingItem, их идентификаторы имеют значение = 0.

Так что мой вопрос: Как я могу извлечь последний вставленный идентификатор

PS: Изменение запроса SQL для SELECT last_insert_rowid() FROM ShoppingItem; дал тот же результат

PPS:. Такие решения, как Getting the Last Insert ID with SQLite.NET in C# не компилируют, по-видимому, есть старая версия SQLite используется, с совершенно другим API

+0

является db.ExecuteScalar ("SELECT last_insert_rowid()"); за работой? (Без, в конце запроса) – Joel

+0

нет, тот же результат с запятой или без нее :( –

+0

Я бы порекомендовал вам выбрать другое имя для вашего столбца «id» pk. Я не знаю, является ли Id чем-то вроде внутреннее ключевое слово, но я просто угадываю здесь. – Joel

ответ

11

Ваш SELECT last_insert_rowid() вызов не работает, потому что вы работаете его подключения к базе данных в разные.

Во всяком случае, вы должны просто читать идентификатор из вставленного ShoppingItem объекта, например:

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

ah, OK, новое соединение - это проблема. Но как я могу прочитать идентификатор от объекта, который я только что вставил? –

+0

взгляните на мое обновленное решение (метод: insertExpenseItem2). Запрос заключен в транзакцию и поэтому использует одно и то же соединение с базой данных. – Joel

+0

Большое вам спасибо. К сожалению, я не нашел хорошей документации о «новом» SQLite. –

0

Это то, что я сделать, чтобы получить идентификатор последнего вставленного элемента . Предоставленный фрагмент кода работает в моем Wi Приложение ndows 8 с использованием 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; 
    } 
} 

Свойство идентификатор в классе FinancialListBoxItem выглядит следующим образом:

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

Я рекомендовал бы выбрать другое имя для рк столбца «Id». Я не знаю, является ли Id чем-то вроде внутреннего ключевого слова. EDIT: Хорошо это не SQLite ключевое слово, но идентификатор не имя собственное в любом случае (Источник: 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 
} 
Смежные вопросы