0

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

我试图避免的问题是每次创建新的 TreeNode 时 TreeView 和 TreeNode_Table 之间的大量“往返”。最好在创建TreeNode之前提前知道 TreeNode_Table 中的下一个自动增量主键是什么。这样我就可以创建节点并将其添加到树中,然后将数据一次性复制到新的 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库来访问数据文件。

感谢您的帮助。有任何想法吗?

4

2 回答 2

2

最好的办法是在使用 SQLiteConnection 对象的 LastInsertRowId 属性插入新的行键后询问它。

于 2012-08-16T20:55:26.650 回答
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

于 2012-08-17T08:06:22.727 回答