Windows Phone 7:SQLite

6

我正在尝试让Community.Csharp与Windows Phone配合使用,我尝试使用http://wp7sqlite.codeplex.com/上的版本以及使用带有WINDOWS_PHONE标志的主干进行编译,但是当我在手机上运行应用程序并尝试执行任何查询时(仅在查询时而不是打开数据库时),我会收到错误信息:"无法打开数据库文件"。

_conn = new SqliteConnection("Version=3,uri=file:recipes.sqlite");
_conn.Open();
cmd.CommandText = "SELECT * FROM recipes";
SqliteDataReader reader = cmd.ExecuteReader();

有趣的是,我正在使用以下代码来检查表是否存在,但没有抛出任何异常:
cmd.CommandText = "SELECT * FROM sqlite_master WHERE name='" + tableName + "'";
SqliteDataReader rdr = cmd.ExecuteReader();
exists = rdr.Read();
rdr.Close();

我有一个使用SQLite的Windows应用程序,如果我能使用SQLite而不是Sterling DB或其他东西,那将节省大量时间。目前我遇到的问题是,一旦我打开数据库并关闭它,我就无法重新打开它。


4
现在已经有100多个问题,所以您应该知道如何格式化您的帖子了。请参见http://stackoverflow.com/editing-help 了解更多信息。 - BoltClock
2个回答

5
我正在为我们公司的应用程序使用同一库,据我所知,http://wp7sqlite.codeplex.com(在“一些建议”下)也有记录。如果关闭连接,则需要重新创建连接。
== 其他评论 ==
我已经找到了错误的原因,创建了一个修复程序,并在我们的应用程序中进行了测试。简而言之,为了将Community.CSharpSqlite库移植到WP7,作者在WP7 IsolatedStorageFileStream周围编写了一个FileStream包装器。当打开db时,会打开并读取db文件流,并由CSharpSqlite关闭。但是,此流的句柄也存储在映射文件路径到流的Dictionary中。第二次打开db时,检索流的句柄,但由于它已关闭(我假设还没有验证),因此db无法打开。
我将尝试将更改部署到wp7sqlite.codeplex.com项目中,但在此期间,如果您有源代码,请对Community.CsharpSqlite.FileStream进行以下更改。
更改为:
    public FileStream(string path, FileMode mode, FileAccess access, FileShare share, int unused)
    {
        IsolatedStorageFileStream handler = null;
        if (FileStream.HandleTracker.TryGetValue(path, out handler))
        {
            _internal = handler;
        }
        else
        {
            if (mode == FileMode.Create || mode == FileMode.CreateNew)
            {
                _internal = IsolatedStorageIO.Default.CreateFile(path);
            }
            else
            {
                _internal = IsolatedStorageIO.Default.OpenFile(path, FileMode.OpenOrCreate);
            }
            FileStream.HandleTracker.Add(path, _internal);
        }
    }

为了

    public FileStream(string path, FileMode mode, FileAccess access, FileShare share, int unused)
    {
        IsolatedStorageFileStream handler = null;
        if(FileStream.HandleTracker.TryGetValue(path, out handler)) 
        {
            _internal = handler;
            if(!_internal.CanRead) 
            {
                FileStream.HandleTracker.Remove(path);
                CreateOpenNewFile(path, mode);
            }
        } else {
            CreateOpenNewFile(path, mode);
        }
    }

    private void CreateOpenNewFile(string path, FileMode mode) 
    {
        if(mode == FileMode.Create || mode == FileMode.CreateNew) 
        {
            _internal = IsolatedStorageIO.Default.CreateFile(path);
        } else {
            try {
                _internal = IsolatedStorageIO.Default.OpenFile(path, FileMode.OpenOrCreate);
            } catch(Exception ex) {
                var v = ex;
            }
        }
        FileStream.HandleTracker.Add(path, _internal);
    }

这是我第一次尝试调试并为开源项目做出贡献。非常欢迎您对这些更改提出任何评论或想法。

阿拉斯代尔。


谢谢,这似乎解决了问题。该项目的源代码命名约定非常类似于C语言。 - Echilon
干得好,加一分!我初步选择@VanSiner的方案,并希望你的代码能尽快被纳入。 :-) - Aasmund Eldhuset

3

您好,我遇到了同样的问题...我认为我已经解决了它。这是我所做的。

  public void CloseDB()
  {
    Connection.Close();               //Connection is a property(of type SqliteConnection) of my object
    FileStream.HandleTracker.Clear(); //This here is the fix
  } 

我其实不需要改变dll文件。
目前我还不确定这样做是否会在以后引起错误,但目前对我来说它是可行的。
...我只是一个初级程序员:D


1
似乎可以工作(至少在一次只打开一个连接的情况下)。如果有其他人被 FileStream 没有 HandleTracker 属性困扰,那是因为这不是 System.IO.FileStream,而是 Community.CsharpSqlite.FileStream - Aasmund Eldhuset

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接