【原创】System.Data.SQLite内存数据库模式
对于很多嵌入式数据库来说都有对于的内存数据库模式,SQLite也不例外。内存数据库常常用于极速、实时的场景,一个很好的应用的场景是富客户端的缓存数据,一般富客户端的缓存常常需要分为落地和非落地两种,而反应到SQLite上就是主要两种模式,一种是文件类型的数据库,一种是内存模式的。而我们常常需要做的是系统启动初从文件数据库加载到内存数据库,然后在系统退出或定时的将内存数据回写到文件数据库。这种导入和导出操作,在C#版本的SQLite库中已经原生进行了支持。而C版本中实际上对应了三个函数,你可以参照SQLite Online Backup API 。
其实本人在查找SQLite的内存模式和文件模式相互备份资料的时候,发现关于使用System.Data.SQLite.dll来进行两种模式相互备份的例子比较少,而且在国内的许多网站上找不到可以直接复用的代码,即时找到了也总是夹杂着很多C版本的实现,总是让人有些摸不着头脑。虽然如此,功夫不负有心人,在stackoverflow上找到了自己想要的代码,通过反编译看System.Data.SQLite.dll看SQLiteConnection中有一个方法BackupDatabase(......),通过它可以实现数据库间的备份。
BackupDatabase(......)方法的反编译的源码如下:
// The method in System.Data.SQLite.SQLiteConnection public void BackupDatabase(SQLiteConnection destination, string destinationName, string sourceName, int pages, SQLiteBackupCallback callback, int retryMilliseconds) { //省略参数检查和连接状态检查代码 // SQLiteBase sql = this._sql; if (sql == null) { throw new InvalidOperationException("Connection object has an invalid handle."); } SQLiteBackup sQLiteBackup = null; try { sQLiteBackup = sql.InitializeBackup(destination, destinationName, sourceName); bool flag; while (sql.StepBackup(sQLiteBackup, pages, out flag) && (callback == null || callback(this, sourceName, destination, destinationName, pages, sql.RemainingBackup(sQLiteBackup), sql.PageCountBackup(sQLiteBackup), flag))) { if (flag && retryMilliseconds >= 0) { Thread.Sleep(retryMilliseconds); } if (pages == 0) { break; } } } catch (Exception ex) { if ((this._flags & SQLiteConnectionFlags.LogBackup) == SQLiteConnectionFlags.LogBackup) { SQLiteLog.LogMessage(0, string.Format(CultureInfo.CurrentCulture, "Caught exception while backing up database: {0}", new object[] { ex })); } throw; } finally { if (sQLiteBackup != null) { sql.FinishBackup(sQLiteBackup); } } }
从上面这段代码我们可以简单的看出,实际上备份还是通过InitializeBackup,StepBackup,FinishBackup这三个方法来实现。这三个方法分别对应的本地方法是sqlite3_backup_init,sqlite3_backup_step,sqlite3_backup_finish;关于这个三个方法的说明可以参考SQLite Online Backup API 。
接下来,将直接贴代码来展示如何在C#中使用System.Data.SQLite.dll来进行SQLite文件数据库与内存数据库相互备份。
// // 软件版权: http://xiexiuli.cnblogs.com/ // 作者: xiexiuli // 创建时间: 2014-01-20 // 功能说明: SQLite内存数据库模式的管理器 // 修改历史: // using System; using System.Collections.Generic; using System.Data; using System.Data.SQLite; using System.IO; namespace LongThinking.Data { /// <summary> /// SQLite内存数据库模式的处理器 /// </summary> public class SQLiteMemoryManager : IDisposable { /// <summary> /// 每个内存数据库都保持一个自己的连接 /// </summary> private SQLiteConnection _globalConnection; #region 构造函数 public SQLiteMemoryManager() { var str = "Data Source=:memory:;Version=3;New=True;"; _globalConnection = new SQLiteConnection(str); _globalConnection.Open(); } #endregion #region 备份数据库 /// <summary> /// 备份数据库 /// </summary> /// <param name="dbFileConnectString">指定到文件数据库路径的连接串</param> /// <param name="isFileToMemory"> /// 是否是文件数据库备份到内存数据库; /// isFileToMemory为true指的是从文件数据库导入到当前内存数据库; /// isFileToMemory为false指的是从当前内存数据库导出到文件数据库。 /// </param> public void BackupDatabase(string dbFileConnectionString, bool isFileToMemory) { using (SQLiteConnection dbfileConnection = new SQLiteConnection(dbFileConnectionString)) { this.BackupDatabase(dbfileConnection, isFileToMemory); } } /// <summary> /// 备份数据库 /// </summary> /// <param name="dbPath">指定到文件数据库的文件全路径</param> /// <param name="password">文件数据库密码</param> /// <param name="isFileToMemory"> /// 是否是文件数据库备份到内存数据库; /// isFileToMemory为true指的是从文件数据库导入到当前内存数据库; /// isFileToMemory为false指的是从当前内存数据库导出到文件数据库。 /// </param> public void BackupDatabase(string dbPath, string password, bool isFileToMemory) { string dbFileConnectString = "Data Source=" + dbPath + ";Pooling=true;FailIfMissing=false;Password=" + password; using (SQLiteConnection dbfileConnection = new SQLiteConnection(dbFileConnectString)) { this.BackupDatabase(dbfileConnection, isFileToMemory); } } /// <summary> /// 备份数据库 /// </summary> /// <param name="dbfileConnection">文件数据库的连接,该连接状态需要是打开的或者是未打开过;关闭状态的连接,默认会帮你打开</param> /// <param name="isFileToMemory"> /// 是否是文件数据库备份到内存数据库; /// isFileToMemory为true指的是从文件数据库导入到当前内存数据库; /// isFileToMemory为false指的是从当前内存数据库导出到文件数据库。 /// </param> public void BackupDatabase(SQLiteConnection dbfileConnection, bool isFileToMemory) { //如果连接是关闭状态就打开 if (dbfileConnection.State == ConnectionState.Closed) { dbfileConnection.Open(); } if (isFileToMemory) { dbfileConnection.BackupDatabase(_globalConnection, "main", "main", -1, null, 0); } else { _globalConnection.BackupDatabase(dbfileConnection, "main", "main", -1, null, 0); } } #endregion #region 销毁 ~SQLiteMemoryManager() { this.Dispose(true); } public void Dispose() { this.Dispose(true); GC.SuppressFinalize(this); } protected void Dispose(bool disposing) { if (disposing) { if (_globalConnection != null) { _globalConnection.Dispose(); } } } #endregion } }
上面的代码我已经删除很多数据操作的方法,等我测试完那些操作方法将提供完整版的类和工程供大家下载。
参考:
http://www.sqlite.org/backup.html
http://stackoverflow.com/questions/17298988/system-data-sqlite-backupdatabase-throws-not-an-error
【原创】System.Data.SQLite内存数据库模式的更多相关文章
- 启用SQLite的Data Provider 运行WECOMPANYSITE时遇到ERROR CREATING CONTEXT 'SPRING.ROOT': ERROR THROWN BY A DEPENDENCY OF OBJECT 'SYSTEM.DATA.SQLITE'
从网上下载的源码WeCompanySite,运行时报错 Error creating context 'spring.root': Error thrown by a dependency of ob ...
- .Net4.0以上使用System.Data.Sqlite
最近对Sqlite感兴趣,就尝试了一下用c#连接,我用的版本是vs2013,默认开发环境是.net4.5,,按照网上的教材,下载了System.Data.Sqlite,然后写了下面这个简单的测试代码, ...
- IIS发布网站出现“未能加载文件或程序集“System.Data.SQLite”或它的某一个依赖项。”的解决方法
未能加载文件或程序集“System.Data.SQLite”或它的某一个依赖项.试图加载格式不正确的程序. 说明: 执行当前 Web 请求期间,出现未经处理的异常.请检查堆栈 ...
- 引用64位dll时候出现 未能加载文件或程序集“System.Data.SQLite”或它的某一个依赖项。试图加载格式不正确的程序。
引用64位dll时候出现 未能加载文件或程序集“System.Data.SQLite”或它的某一个依赖项.试图加载格式不正确的程序. 需要在web.config增加配置 <startup use ...
- Could not load file or assembly 'System.Data.SQLite' or one of its dependencies
试图加载格式不正确的程 异常类型 异常消息Could not load file or assembly 'System.Data.SQLite' or one of its dependencies ...
- System.Data.SQLite
SQLite介绍 在介绍System.Data.SQLite之前需要介绍一下SQLite,SQLite是一个类似于Access的单机版数据库管理系统,它将所有数据库的定义(包括定义.表.索引和数据本身 ...
- 未能加载文件或程序集“System.Data.SQLite.DLL”或它的某一个依赖项
今天在部署code到测试环境的时候 出现了未能加载文件或程序集"System.Data.SQLite.DLL"或它的某一个依赖项 这个错误,其实错误的的原因有很多,1.典型的是是版 ...
- SQLite 解决:Could not load file or assembly 'System.Data.SQLite ... 试图加载格式不正确的程序/or one of its dependencies. 找不到指定的模块。
Could not load file or assembly 'System.Data.SQLite.dll' or one of its dependencies. 找不到指定的模块. 错误提示 ...
- 能加载文件或程序集“System.Data.SQLite”或它的某一个依赖项。试图加载格式不正确的程序。
现象: 能加载文件或程序集“System.Data.SQLite”或它的某一个依赖项.试图加载格式不正确的程序.
随机推荐
- Qt相关问题
1. Qt编译中的error: cannot find -lGL和 error: collect2: error: ld returned 1 exit status 一般见于新安装的系统,马上就直 ...
- 怎么实现类似星星闪烁的效果(box-shadow)
有时候设计希望我们能够在页面实现类似星星闪烁的效果,如图: 我的解决办法是用box-shadow: html <div class="star04 active-blink" ...
- css-网页整体css布局
<!DOCTYPE html><!--有限宽度带居中布局:<style>*{margin:0;padding:0;list-style:none;} .zong{back ...
- Android --------- 标签include位置设置无效
给include设置below或align无效,是因为没有给include设置width和height.
- SQL Server -SET QUOTED_IDENTIFIER
SET QUOTED_IDENTIFIER ON SQL SERVER的联机丛书的解释: “当 SET QUOTED_IDENTIFIER 为 ON 时,标识符可以由双引号分隔,而文字必须由单引号分隔 ...
- scala maven pom文件
老司机的spark maven pom文件 pom文件一: 4.0.0 <groupId>com.glsx</groupId> <artifactId>spark- ...
- JAVA操作properties文件
va中的properties文件是一种配置文件,主要用于表达配置信息,文件类型为*.properties,格式为文本文件,文件的内容是格式是"键=值"的格式,在properties ...
- shell脚本练习(autocert)
#!/bin/bash#By Spinestars#20131118 #name:ca_cert#certficate ca cd /etc/pki/CA/auto num=$RANDOM mv ./ ...
- C语言基础10
栈区间:在函数内部声明的变量都存放在栈区间,比如int char 数组 结构体 指针,只管申请,系统会自动帮我们回收,收回的时间是作用域结束之后,遵循的原则是"先进后出". int ...
- Java Spring MVC
Spring MVC的实现包括 实现Controller类和基于注解的Controller RequstMapping方式 依赖: <!-- https://mvnrepository.com/ ...