【原创】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”或它的某一个依赖项.试图加载格式不正确的程序.
随机推荐
- 前端--关于CSS文本
文本是网页中最重要的一种内容形式,文本几乎可以写在任何地方,块级元素中可以写行内元素中也可以写.文本都是由一个个字符组成的 ,在css布局中,每一个字符都有一个em框,通常font-size设置的大小 ...
- QQ浏览器不支持JS问题
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- OpenCV——Haar-like特征
Haar-like特征--即Haar特征,是计算机视觉领域一种常用的特征描述算子.它最早用于人脸描述. 目前常用的Haar-like特征可以分为以下几类:线性特征.边缘特征.点特征(中心特征).对角线 ...
- Install cv2.so for Anaconda
sudo apt-get install python-opencv cp /usr/lib/python2.7/dist-packages/cv2.so /opt/anaconda/lib/pyth ...
- jquery 源码分析
想给自己一个任务,接下来要分析jquery源码,然后按照jquery的思想打造一个适合webkit的类jquery微框架,一切从模仿起!
- 关于安卓的log学习
什么时候会产生log文件? 1. 程序异常退出 Uncaused Exception. 2. 程序强制关闭 Force Closed(FC). 3. 程序无响应 Application No Resp ...
- haproxy之配置文件解析
功能--> 提供高可用/负载均衡/基于tcp和http应用的代理;支持虚拟主机,特别适用于负载特大的web站点. 配置文件解析--> #配置文件-->开启/proc/net/ipv4 ...
- sqlserver系统表操作
查询表名中包含‘user’的方法Select * From sysobjects Where name like '%user%' 如果知道列名,想查找包含有该列的表名,可加上系统表syscolumn ...
- Clojure操作mysql
在Eclipse中新建一个Clojure工程clj01 clojure 操作mysql需要依赖mysql-connector-java.clojure-contrib与java.jdbc三个jar包. ...
- C# Url编码 HtmlUrl编码
今天看了Artwl的一片关于编码的文章,感觉写的非常好,而且人家那博客园的样式都比哥的好看得多,一幕了然,尤其是那黑色背景的H1,妈个B了,哥太喜欢了.既然如果,就来就着它的文章跟样式,顺便来总结一下 ...