【问题标题】:WP8/C#/SQLite: get last inserted id?WP8/C#/SQLite:获取最后插入的 id?
【发布时间】:2013-03-18 11:47:25
【问题描述】:

带有 WP8 的 SQLite 让我抓狂。 :(

我要做的就是检索最后插入的 id 的值...

我有:

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 的所有条目时,它们的 ID 的值是 != 0。

所以我的问题是:如何检索最后插入的 id?

PS:将 SQL 查询更改为 SELECT last_insert_rowid() FROM ShoppingItem; 得到相同的结果。

PPS:Getting the Last Insert ID with SQLite.NET in C# 之类的解决方案无法编译,显然使用的是旧版本的 SQLite,其 API 完全不同

【问题讨论】:

  • 是 db.ExecuteScalar("SELECT last_insert_rowid()");在职的? (没有 ; 在查询的末尾)
  • 不,有或没有分号的结果相同:(
  • 我建议您为您的 pk 列“Id”选择一个不同的名称。我不知道 Id 是否类似于内部关键字。但我只是在这里猜测。
  • 不,将其更改为 myId。 :(

标签: c# sqlite windows-phone-8


【解决方案1】:

您的SELECT last_insert_rowid() 调用不起作用,因为您在不同 数据库连接中运行它。

无论如何,您应该只从插入的ShoppingItem 对象中读取 ID,如下所示:

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

【讨论】:

  • 啊,好的,新连接就是问题所在。但是如何从我刚刚插入的对象中读取 ID?
  • 看看我更新的解决方案(方法:insertExpenseItem2)。查询被封装到一个事务中,因此使用相同的数据库连接。
  • 非常感谢。不幸的是,我没有找到任何关于“新”SQLite 的好的文档。
  • 感谢先生,它在 UWP 上与 SQLite.net 配合得非常好。
【解决方案2】:

这就是我检索最后插入项目的 id 的方法。提供的代码 sn-p 在我使用 SQLite 3.7.XX (SQLite) 的 Windows 8 应用程序中工作。

    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 类中的 id 属性如下所示:

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

我建议您为 pk 列“Id”选择不同的名称。我不知道 Id 是否类似于内部关键字。 编辑:好吧,它不是 SQLite 关键字,但 id 无论如何都不是正确的名称(来源:SQLite Keywords)

【讨论】:

    【解决方案3】:
       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
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-08-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-12
      • 2011-11-26
      • 1970-01-01
      相关资源
      最近更新 更多