0

Winforms TreeViewがあり、ノード データを SQLite テーブルに保存して、次回アプリケーションを起動したときに TreeView を復元できるようにしたいと考えています。TreeView を使用してほとんどのデスクトップ アプリケーションを操作し、TreeNodes にアタッチされたクラス内のインデックス ポインター フィールドを使用して、ユーザーがノードをクリックしたときにデータベース内の他のテーブルにアクセスします。

私が回避しようとしている問題は、新しい TreeNode が作成されるたびに、TreeView と TreeNode_Table の間で多くの「往復」が発生することです。TreeNodeを作成するに、次の自動インクリメント主キーがTreeNode_Tableにあることを事前に知っておくとよいでしょう。そうすれば、ノードを作成してツリーに追加し、データを新しい TreeNode_Table 行に 1 回のパスでコピーできます。主キー、ノード レベル、ノード インデックス、およびその他のノードと行の値などの値を同期するための、テーブルと 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])に 1 を追加すると機能しなくなります。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 に答える