我想从给定的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();
}
}
所以我想,还有一种方法可以用直接(解密)流来做到这一点!?
答案 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;