【原创】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”或它的某一个依赖项.试图加载格式不正确的程序.
随机推荐
- NET基础课--泛型(NET之美)
1.泛型,类型或方法的一种抽象概括. 2.泛型类:在类型名后面加一个<>,其中传递占位符,也就是类型参数.where是类型约束 可以再查资料 public class SortHelper ...
- (转)SQL Server 触发器
SQL Server 触发器 触发器是一种特殊类型的存储过程,它不同于之前的我们介绍的存储过程.触发器主要是通过事件进行触发被自动调用执行的.而存储过程可以通过存储过程的名称被调用. Ø 什么是触发器 ...
- ASP.NET MVC:自定义 Route 生成小写 Url(转)
先给出本文中测试用的 controller: public class PersonsController : Controller { public ActionResult Query(strin ...
- C++单链表的创建与操作
链表是一种动态数据结构,他的特点是用一组任意的存储单元(可以是连续的,也可以是不连续的)存放数据元素.链表中每一个元素成为“结点”,每一个结点都是由数据域和指针域组成的,每个结点中的指针域指向下一个结 ...
- OpenSSl编译
1.下载openssl代码,下载地址:http://www.openssl.org/source/ ,如果使用winrar解压失败的话(提示不能创建符号链接),可以关闭UAC.2.下载安装Active ...
- SQL语句 计算某段时间工作日的天数(除了周六日)
--只是加了固定日期,可以根据需求给成变量形式(BY 少年工藤) -思路:根据日期区间循环判断每一天是周日(1).周六(7)不变,其他加1 1 DECLARE @DAY DATE,@COUNT INT ...
- ExtJs 学习笔记
1.显示中文 <script type="text/javascript" src="../../locale/ext-lang-zh_CN.js"&g ...
- jQuery中的$.extend方法总结
原文见:jQuery.extend()函数详解 Jquery的扩展方法extend是我们在写插件的过程中常用的方法,但是经常容易搞不清楚以下两个写法的关系: 1.$.extend(dest,src1, ...
- spring3+hibernate3+(dbcp+oracle+拦截器事务配置)整合(一)
1.applicationContext-base.xml文件 <?xml version="1.0" encoding="UTF-8"?>< ...
- 【转】nginx之逻辑运算
nginx的配置中不支持if条件的逻辑与&& 逻辑或|| 运算 ,而且不支持if的嵌套语法,否则会报下面的错误:nginx: [emerg] invalid condition. 我们 ...