2

私は検索に疲れたので、誰かが同じ問題を抱えていて私を助けることができることを願って、ここで私の最初のSOの質問に行きます

ゴール

SQLiteデータベースでアプリケーションデータを保存しようとしています

アプリケーションの説明

Windowsランタイム拡張用のSQLitesqlite-netライブラリを使用したローカルSQLiteデータベースを備えたWindows8アプリC#XAML

テーブル定義

public class Product {
    private int _id;

    [SQLite.PrimaryKey, SQLite.AutoIncrement]
    public int ID
    {
        get { return _id; }
        set { _id = value; }
    }

    private string _date;
    public string DATE
    {
        get { return _date; }
        set { _date = value; }
    }

    private string _desc;
    public string DESC
    {
        get { return _desc; }
        set { _desc = value; }
    }
}

問題1

public int Insert (object obj)説明には次のように書かれています。

指定されたオブジェクトを挿入し、自動インクリメントされた主キーがある場合はそれを取得します。

ただし、行を挿入するたびに1が返されます。自動インクリメントIDで正常に挿入できますが、どういうわけかIDが返されません。なんで?

問題2

新しい行を挿入することはできますが、削除することはできません

問題1を回避して、最後の行で生成されたIDを取得し、行を削除しようとしましたが、成功しませんでした。

常に失敗する次のテスト例を参照してください。

using (var db = new SQLiteConnection(Path.Combine(_path, _dbname)))
{
    var p1 = new Product() { DESC = "insert1", DATE = DateTime.Now.ToString() };
    db.Insert(p1);
    p1.ID = 1;
    var p2 = new Product() { DESC = "insert2", DATE = DateTime.Now.ToString() };
    // I am sure that this row is getting ID 2, so it will not have a wrong ID
    p2.ID = 2;
    db.Insert(p2);
    var p3 = new Product() { DESC = "insert3", DATE = DateTime.Now.ToString() };
    db.Insert(p3);
    p3.ID = 3;
    db.Delete<Product>(p2);
}

ご覧のとおり、3行を挿入し、2行目を削除しようとしています。行は挿入されますが、次のSQLite.SQLiteException例外が発生します。

未完了のステートメントまたは未完了のバックアップのために閉じることができません

なんで?その前後に他の接続を開きません。


前もって感謝します

解決しました

問題1

+1と、関数が説明と一致しないことを指摘してくれた@Bridgeyと、関連する検索に感謝します

この関数は、言うようにIDを返しませんが、オブジェクトIDを定義します。したがって、新しいProductを挿入すると、Product.IDには最後に挿入されたIDが含まれます。

問題2

に変更db.Delete<Product>(p2);しましたがdb.Delete(p2);、動作します。SQLite-netは、行をProductとして正しく識別します。未完了のステートメントまたは未完了のバックアップ例外が原因で閉じることができない理由がまだわかりません。誰かが理由を知っているなら教えてください。

4

1 に答える 1

4

問題2の場合、問題は、DeleteメソッドのパラメーターとしてProductオブジェクトを渡していることだと思います。ドキュメントには次のように書かれています。指定された主キーを持つオブジェクトを削除します。私は次のことがうまくいくと思います:

db.Delete<Product>(p1.ID);

問題1に関しては、sqlite-netパッケージのInsertメソッドのコードが終了します。

var count = insertCmd.ExecuteNonQuery (vals);

if (map.HasAutoIncPK) {
  var id = SQLite3.LastInsertRowid (Handle);
  map.SetAutoIncPK (obj, id);
}

return count;

ご覧のとおり、が設定されcountていても返さidれます。

編集:実際、著者によると、これは意図的なものです。「挿入は、変更された行数を返します。自動インクリメントされた列はオブジェクトに格納されます。ドキュメントのコメントを参照してください。」 https://github.com/praeclarum/sqlite-net/issues/37

于 2013-02-21T23:14:41.530 に答える