0

私の C# アプリケーションでは、SQL Compact データベースとやり取りしています。このコンテキストでは、3 つのテーブルがあります。customerlist、およびcustomerlist(顧客とリストは多対多の関係です)。

リストを削除したいときに呼び出す関数があります。この関数は、関連するエントリもcustomerlistテーブルから削除します。これは、クリーンアップのためです (リスト自体が削除された場合、関連するエントリは無効になるため)。

私のコードは次のとおりです。

    private void clearRedundantSubscriptions()
    {
        string sql;
        // Check if there are any entries in customerlist table which point to non-existing lists
        try
        {
            sql = "select distinct cl.listid from customerlist cl inner join list l on cl.listid != l.listid";
            SqlCeCommand cmdGetDisusedLists = new SqlCeCommand(sql, DbConnection.ceConnection);
            SqlCeDataReader reader = cmdGetDisusedLists.ExecuteReader();
            while (reader.Read())
            {
                DbFunctions.DeleteList(reader.GetInt32(0), false, false);
            }
        }
        catch (Exception ex)
        {
            MessageBox.Show("Error cleaning up list entries." + ex.Message);
        }
        return;
    }

    public static bool DeleteList(int id, bool display, bool close)
    {
        string sql;
        string title = "";
        bool ranOk = false;
        try
        {
            sql = "select ShortDesc from list where listid=" + id;
            DbFunctions.runSQL(sql, out title);
            sql = "delete from list where ListId=" + id;
            SqlCeCommand cmdDelList = new SqlCeCommand(sql, DbConnection.ceConnection);
            cmdDelList.ExecuteNonQuery();
            sql = "delete from customerlist where listid=" + id;
            SqlCeCommand cmdDelEntries = new SqlCeCommand(sql, DbConnection.ceConnection);
            cmdDelEntries.ExecuteNonQuery();
            if (display)
                General.doneWork(title + " list deleted.");
            ranOk = true;
        }
        catch (Exception ex)
        {
            if (display)
                MessageBox.Show("Unable to delete list. " + ex.Message);
        }
        finally
        {
            if (close)
                DbConnection.closeConnection();
        }
        return ranOk;
    }

    public static void closeConnection()
    {
        if (_sqlCeConnection != null)
            _sqlCeConnection.Close();
    }

お気づきでしょうが、私の deletelist 関数では、'close' という名前の bool パラメーターを渡しています。リーダー内でデータベースへの接続を閉じると上記のエラーが発生したため、これを追加しました。したがって、この関数をリーダー内で使用する場合は、deleteList 関数を呼び出して、「close」パラメーターが として渡されるようにしfalseます。それは問題ではありません。これは、この関数で DbConnection.closeConnection が呼び出されないことを意味します。

したがって、リーダーもデータベース接続も閉じていません。それでもこのエラーが発生する理由はありますか?

4

1 に答える 1

1

コードを変更しました。これを試してください。

DbFunctions.runSQL メソッド内で何が起こっているのかわかりません。そのため、その呼び出しの前に接続を再度開く必要があるかもしれません。

private void clearRedundantSubscriptions()
{
    string sql;
    // Check if there are any entries in customerlist table which point to non-existing lists
    var list = new List<int>();
    try
    {
        if (DbConnection.ceConnection.State == ConnectionState.Closed)
            DbConnection.ceConnection.Open();

        sql = "select distinct cl.listid from customerlist cl inner join list l on cl.listid != l.listid";

        SqlCeCommand cmdGetDisusedLists = new SqlCeCommand(sql, DbConnection.ceConnection);
        SqlCeDataReader reader = cmdGetDisusedLists.ExecuteReader();
        while (reader.Read())
        {
            list.Add(reader.GetInt32(0));
        }
    }
    catch (Exception ex)
    {
        MessageBox.Show("Error cleaning up list entries." + ex.Message);
        throw;
    }
    finally
    {
        DbConnection.closeConnection();
    }

    foreach(var id in list)
    {
        DeleteList(id,false);

    }
    return;
}

public static bool DeleteList(int id, bool display)
{
    string sql;
    string title = "";
    bool ranOk = false;
    try
    {
        sql = "select ShortDesc from list where listid=" + id;
        DbFunctions.runSQL(sql, out title);


        sql = "delete from list where ListId=" + id;
        SqlCeCommand cmdDelList = new SqlCeCommand(sql, DbConnection.ceConnection);
        cmdDelList.ExecuteNonQuery();
        sql = "delete from customerlist where listid=" + id;
        SqlCeCommand cmdDelEntries = new SqlCeCommand(sql, DbConnection.ceConnection);
        cmdDelEntries.ExecuteNonQuery();
        if (display)
            General.doneWork(title + " list deleted.");
        ranOk = true;
    }
    catch (Exception ex)
    {
        if (display)
            MessageBox.Show("Unable to delete list. " + ex.Message);
    }
    finally
    {
            DbConnection.closeConnection();
    }
    return ranOk;
}

public static void closeConnection()
{
    if (_sqlCeConnection != null)
        _sqlCeConnection.Close();
}
于 2013-03-22T12:06:26.407 に答える