3
class SQLiteDatabase
    {
        String dbConnection;
        static SQLiteConnection cnn;
        static int connections = 0;
        /// <summary>
        ///     Default Constructor for SQLiteDatabase Class.
        /// </summary>
        public SQLiteDatabase()
        {
            dbConnection = "Data Source=SQLiteOphthaMetrics.db;foreign keys=true;";
            if (connections == 0)
            {
                cnn = new SQLiteConnection(dbConnection);
                cnn.Open();
                this.ExecuteNonQuery("CREATE TABLE IF NOT EXISTS patients ( id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL, birthday TEXT, gender TEXT, iriscolor INTEGER);");
                this.ExecuteNonQuery("CREATE TABLE IF NOT EXISTS images ( nameRed TEXT NOT NULL PRIMARY KEY, checksumRed TEXT NOT NULL, "
                    + "nameGreen TEXT NOT NULL, checksumGreen TEXT NOT NULL, state INTEGER, cvalue REAL, sharpness REAL, deviation REAL, area REAL, redExposure REAL, "
                    + "redGain REAL, greenExposure REAL, greenGain REAL, zfocus INTEGER, flipped INTEGER, patientID INTEGER, FOREIGN KEY (patientID) REFERENCES patients(id));");
            }
            connections++;
        }

        ~SQLiteDatabase()
        {
            connections--;
            if (connections == 0)
            {
                cnn.Close();
                cnn.Dispose();
            }
        }
    }

このコードは DisposedObjectException をスローします

System.ObjectDisposedException was unhandled
  Message=Auf das verworfene Objekt kann nicht zugegriffen werden.
Objektname: "SQLiteConnection".
  Source=System.Data.SQLite
  ObjectName=SQLiteConnection
  StackTrace:
       bei System.Data.SQLite.SQLiteConnection.CheckDisposed()
       bei System.Data.SQLite.SQLiteConnection.Close()
       bei EyeScanner.SQLiteDatabase.Finalize()
  InnerException: 

現在、コードで SQLiteDatabase を 1 回だけ呼び出しているため、デストラクタで接続 = 1 になっていますが、クラス デストラクタが終了する前にオブジェクトを破棄する理由がわかりません。

4

1 に答える 1

6

クラスインスタンスを破棄する準備ができたら、接続を破棄しようとしていると思います。usingSQLiteConnection でステートメントを使用するとよいでしょう。SQLiteConnection クラスは IDisposable を実装し、次のことができるようになります。

using(cnn = new SQLiteConnection(dbConnection))
{
     cnn.Open();
     this.ExecuteNonQuery("...your query");
}

これはtry/finallyブロックとして機能し、例外が発生した場合でも、接続は閉じられ、usingブロックの後に破棄されます。

データベース接続に関しては、できるだけ遅く開き、できるだけ早く閉じるのが最善の方法です。

于 2012-10-18T09:36:51.663 に答える