【原创】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”或它的某一个依赖项.试图加载格式不正确的程序.
随机推荐
- 同一DataTable下创建多个结构数据相同的DataView的小问题
昨天在根据经理的要求修改公司后台的时候,遇到了一个很奇怪的问题 DataView dvFocus = ]); DataView dvLook = ]); DataView dvNewUser = ]) ...
- Sql server Lock
http://www.cnblogs.com/wuyifu/archive/2013/11/28/3447870.html
- (转)swfobject.js 详细解说
一直想对这个应用做个总结,今天偶然百度到这个效果,为此做个笔记. 用这个js的好处: 1.IE中没有讨厌的虚框问题了.2.提供了完善的版本检测功能,如果版本不够则显示其他东西,比如图片或文字.3.易于 ...
- Ajax与ashx异步请求的简单案例
Ajax与ashx异步请求的简单案例: 前台页面(aspx): <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//E ...
- 对Lucene PhraseQuery的slop的理解[转载]
所谓PhraseQuery,就是通过短语来检索,比如我想查“big car”这个短语,那么如果待匹配的document的指定项里包含了"big car"这个短语,这个documen ...
- (原+转)C++中的lambda表达式
转载请注明出处: http://www.cnblogs.com/darkknightzh/p/5073376.html 参考网址: http://www.cnblogs.com/zhuyp1015/a ...
- WPF下YUV播放的D3D解决方案
http://blog.csdn.net/yangyy9611/article/details/17464133
- Yii 安装
// 安装 composer curl -s http://getcomposer.org/installer | php // 把 composer 添加到全局命令 mv composer.phar ...
- php 实现传入参数的传出
类似于.net的out功能,php中可以使用&实现 如下示例: <?php$x=2; inOutFunction($x); function inOutFunction(&$x) ...
- DOT + graphviz 轻松画图
一.简介DOT & graphviz1. DOT DOT是一种文本图形描述语言.DOT语言文件通常具有.gv或是.dot的文件扩展名.当然,在编写好.dot或者.gv的文件之后,需要有专 ...