从流中打开/关闭数据库

时间:2014-05-25 12:13:25

标签: c# sqlite

我想从给定的Stream(FileStream / Memorystream)访问SQLite数据库?

这是我的代码到目前为止(它将文件读入Memorystream然后在SQLite中打开):

if (File.Exists(path_DB))
{
    byte[] file = File.ReadAllBytes(path_DB);
    MemoryStream mem = new MemoryStream(file);

    using (SQLiteConnection destination = new SQLiteConnection("Data Source=" + mem + ";Version=3;"))
    {
        destination.Open();

        using (SQLiteCommand command = new SQLiteCommand())
        {
            command.Connection = destination;
            command.CommandText = "SELECT Name FROM MyTable;";

            using (SQLiteDataReader reader = command.ExecuteReader())
            {
                while (reader.Read())
                {
                    MessageBox.Show(reader["Name"].ToString());
                }
            }
        }
    }
}

此代码触发我

  

SQL逻辑错误或缺少数据库,没有这样的表:MyTable

command.ExecuteReader()path_DB引用的文件确实有表格。

我哪里出错了?

//编辑:已更改

byte[] file = File.ReadAllBytes(path_DB);
MemoryStream mem = new MemoryStream();

byte[] file = File.ReadAllBytes(path_DB);
MemoryStream mem = new MemoryStream(file);

并且我可以将现有的数据库加载到内存中,并将内存DB再次保存到磁盘,如下所示:

if (File.Exists(path_DB))
{
    using (SQLiteConnection destination = new SQLiteConnection("Data Source=:memory:;Version=3;"))
    {
        SQLiteConnection source = new SQLiteConnection("Data Source=" + path_DB + ";Version=3;"); //;Password=" + textBox2.Text + "
        source.Open();

        destination.Open();

        source.BackupDatabase(destination, "main", "main", -1, null, 0);
        source.Close();

        using (SQLiteCommand command = new SQLiteCommand())
        {
            command.Connection = destination;
            command.CommandText = "SELECT Name FROM MyTable;";

            using (System.Data.SQLite.SQLiteDataReader reader = command.ExecuteReader())
            {
                while (reader.Read())
                {
                    MessageBox.Show(reader["Name"].ToString());
                }
            }
        }

        source = new SQLiteConnection("Data Source=" + path_DB + ";Version=3;"); //;Password=" + textBox2.Text + "
        source.Open();

        // save memory db to file
        destination.BackupDatabase(source, "main", "main", -1, null, 0);
        source.Close();
    }
}

所以我想,还有一种方法可以用直接(解​​密)流来做到这一点!?

1 个答案:

答案 0 :(得分:2)

您的代码存在多个问题以及您尝试做的事情。

首先,您要分配给file但不对其做任何事情。

接下来,您只能在您的连接中添加MemoryStream实例。如documentation

所示
  

强制SQLite数据库纯粹存在于内存中的最常用方法是使用特殊文件名":memory:"打开数据库。换句话说,不是将真实磁盘文件的名称传递给sqlite3_open(),sqlite3_open16()或sqlite3_open_v2()函数之一,而是传入字符串":memory:"。

这意味着在连接字符串中,您需要:memory:作为数据源。这也显示在https://www.connectionstrings.com/sqlite/

Data Source=:memory:;Version=3;New=True;

最后,我之前提到的文档中的另一个片段是:

  

完成此操作后,不会打开任何磁盘文件。而是在内存中创建一个新的数据库。数据库连接关闭后,数据库就不再存在。 Every:memory:数据库彼此不同。因此,打开两个数据库连接,每个连接都有文件名":memory:"将创建两个独立的内存数据库。

这意味着您无法使用现有数据库。您创建一个数据库,使用它然后再次销毁它。文件级别没有持久性。

如果这一切对您没有任何意义,并且您只想使用驱动器上的数据库,请使用如下连接字符串:

Data Source=c:\mydb.db;Version=3;

SQLite提供程序将负责打开文件,从中读取并写入文件。

有关加密问题,请you can use a password for the database。这将负责加密数据库

Data Source=c:\mydb.db;Version=3;Password=myPassword;