在“创建新行”之前确定新的自动增量主键值

时间:2012-08-16 20:48:13

标签: c# sqlite system.data.sqlite

我有一个 Winforms TreeView ,我希望将节点数据存储到SQLite表中,这样我可以在下次启动应用程序时恢复TreeView。我使用TreeView来驱动大多数桌面应用程序,并在附加到TreeNodes的类中使用索引指针字段,以在用户单击节点时访问数据库中的其他表。

我试图避免的问题是每次创建新的TreeNode时TreeView和TreeNode_Table之间的很多“往返”。如果我提前知道 中的下一个自动增量主键,我会创建TreeNode。这样我就可以创建节点并将其添加到树中,然后在一次传递中将数据复制到新的TreeNode_Table行中。表和TreeView之间不会往返,以同步主键,节点级别,节点索引以及其他节点和行值等值。

我试过了:

string strFindLastRowInserted = @"SELECT MAX([id]) FROM [TreeNode_Table];";
var findLastRowInsertedCmd = new SQLiteCommand(strFindLastRowInserted, _cnn);
object resultObj = findLastRowInsertedCmd.ExecuteScalar();
findLastRowInsertedCmd.Dispose();
if( resultObj != null)
NodeTagDataObj.DataPtr = (long)resultObj + 1;    

但如果之前删除了一些最近创建的节点/行,则向 MAX([id])添加一个会中断。我正在使用 System.Data.Sqlite 库来访问数据文件。

感谢您的帮助。有什么想法吗?

2 个答案:

答案 0 :(得分:2)

最好的办法是在使用LastInsertRowId属性插入SQLiteConnection对象后请求新的行密钥。

答案 1 :(得分:1)

我终于通过在Sqlite的表元数据中探测来解决这个问题。要在 之前可靠地获取下一步自动增量键值 ,创建新行,可以使用以下SQL:

SELECT [seq] + 1 FROM [sqlite_sequence] WHERE [name] = 'my_table_name';

我在我的SqliteHelper类中添加并测试了以下静态帮助器方法,并且所有内容都按预期工作,并且逻辑在最近的行删除,断开连接和应用程序重新启动后仍然存在。

SqliteHelper.cs:

internal static long GetNextAutoincrementValue(SQLiteConnection cnn, 
                                               string tableName)
{
    long returnValue = -1;
    SQLiteCommand myCommand = cnn.CreateCommand();  
    myCommand.CommandText = 
        @"SELECT [seq] + 1 FROM [sqlite_sequence] WHERE [name] = @MyTableName;";

    SQLiteParameter myParam = new SQLiteParameter("@MyTableName",
                                                  System.Data.DbType.String);
    myParam.Value = tableName.Trim();
    myCommand.Parameters.Add(myParam);
    object resultObj = myCommand.ExecuteScalar();
    myCommand.Dispose();
    if( resultObj != null)
        returnValue = (long)resultObj;
    return returnValue;
}

我希望其他人会觉得这很有用......

-DougC