使用在mono下运行的sqlite获取“无法打开数据库文件”

时间:2014-01-23 03:29:20

标签: c# sqlite mono

我的第一次发帖。

我制作了一个在后台运行的控制台应用程序,它是用C#编写的,我使用sqlite3来存储它的信息。它是在单声道下运行但我在运行好几天后得到unable to open database file。重启应用程序解决问题,但几天后它会给我同样的错误。

我怀疑是关闭后没有得到处理的连接所以我在connection.close()之后添加了dispose但仍然得到了相同的错误。我也做了一些搜索,发现this thread有类似的问题,我做了他说的但仍然得到同样的错误。

任何帮助将不胜感激。

抱歉英语不好

更新: 我的代码

private static void ExecuteNonQuery(string query)
    {
        if (isrunningundermono == true)
        {
            SqliteConnection sqlcon = new SqliteConnection(ConfigurationManager.AppSettings["connectionString"]);
            SqliteCommand sqlcmd;

            sqlcon.Open();
            sqlcmd = sqlcon.CreateCommand();
            sqlcmd.CommandText = query;
            sqlcmd.ExecuteNonQuery();
            sqlcon.Close();
            sqlcmd.Dispose();
            sqlcon.Dispose();
        }
        else
        {
            SQLiteConnection sqlcon = new SQLiteConnection(ConfigurationManager.AppSettings["connectionString"]);
            SQLiteCommand sqlcmd;

            sqlcon.Open();
            sqlcmd = sqlcon.CreateCommand();
            sqlcmd.CommandText = query;
            sqlcmd.ExecuteNonQuery();
            sqlcon.Close();
            sqlcmd.Dispose();
            sqlcon.Dispose();
        }
    }

    private static int ExecuteScalar(string query)
    {
        if (isrunningundermono == true)
        {
            SqliteConnection sqlcon = new SqliteConnection(ConfigurationManager.AppSettings["connectionString"]);
            SqliteCommand sqlcmd;

            sqlcon.Open();
            sqlcmd = sqlcon.CreateCommand();
            sqlcmd.CommandText = query;
            int total = Convert.ToInt32(sqlcmd.ExecuteScalar());
            sqlcon.Close();
            sqlcmd.Dispose();
            sqlcon.Dispose();

            return total;
        }
        else
        {
            SQLiteConnection sqlcon = new SQLiteConnection(ConfigurationManager.AppSettings["connectionString"]);
            SQLiteCommand sqlcmd;

            sqlcon.Open();
            sqlcmd = sqlcon.CreateCommand();
            sqlcmd.CommandText = query;
            int total = Convert.ToInt32(sqlcmd.ExecuteScalar());
            sqlcon.Close();
            sqlcmd.Dispose();
            sqlcon.Dispose();

            return total;
        }
    }

    private static DataTable ExecuteDataSet(string query)
    {
        if (isrunningundermono == true)
        {
            DataTable dt = new DataTable();
            SqliteConnection sqlcon = new SqliteConnection(ConfigurationManager.AppSettings["connectionString"]);
            SqliteCommand sqlcmd = new SqliteCommand(sqlcon);
            sqlcon.Open();
            sqlcmd.CommandText = query;
            SqliteDataReader reader = sqlcmd.ExecuteReader();
            dt.Load(reader);
            reader.Close();
            sqlcon.Close();
            sqlcmd.Dispose();
            sqlcon.Dispose();

            return dt;
        }
        else
        {
            DataTable dt = new DataTable();
            SQLiteConnection sqlcon = new SQLiteConnection(ConfigurationManager.AppSettings["connectionString"]);
            SQLiteCommand sqlcmd = new SQLiteCommand(sqlcon);
            sqlcon.Open();
            sqlcmd.CommandText = query;
            SQLiteDataReader reader = sqlcmd.ExecuteReader();
            dt.Load(reader);
            reader.Close();
            sqlcon.Close();
            sqlcmd.Dispose();
            sqlcon.Dispose();

            return dt;
        }
    }

    public static bool IsRunningOnMono()
    {
        return Type.GetType("Mono.Runtime") != null;
    }

1 个答案:

答案 0 :(得分:1)

SQLiteConnection.Dispose内部只调用SQLiteConnection.Close,所以你仍然在命令之前有效地关闭连接,我猜这是Mono上的问题。我想如果你只是删除对sqlcon.Close的显式调用,你会看到更好的结果。

顺便说一下,在处理IDisposable实例时习惯使用using statement,例如:

using (var conn = new SQLiteConnection(...))
{
  conn.Open();
  using (var cmd = new SQLiteCommand(conn))
  {
  }
}

我认为在连接之前处理命令是很自然的,因为命令使用了连接(并且using语句有助于保持这种直接),但我认为没有理由为什么反向可以在Windows上工作但不在Mono上工作...