【原创】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”或它的某一个依赖项.试图加载格式不正确的程序.
随机推荐
- 推荐几本不错的ASP.NET MVC书
以前主要是做PHP应用的,由于工作需要,捡起来.NET, 特别是新技术层出不穷,找了几本书看,个人感觉还不错,网上也有电子版的下载 一. ASP.NET MVC4 Web 编程 O'Reilly出版社 ...
- 怎么使用jQuery在DIV适应屏幕大小一直居中
js的代码是这样的: $(function(){ $(window).resize(function(){ $(".login").css({ position: "ab ...
- javascript 之 this 用法
参考视频:http://www.imooc.com/video/6430 JavaScript中的this比较灵活,也是让很多初学者摸不到头脑,那么根据在不同的环境下,在同一个函数,不同的调用方式下, ...
- jquery简单切换插件
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta http ...
- 简化工作——我的bat文件
重启adb(radb.bat): @echo off call adb kill-server call adb start-server call adb remount push 一个apk(pu ...
- SQL 用中文的拼音和笔画排序
SQL 用中文的拼音和笔画排序 城市按拼音排序: SELECT chineseName FROM [表名] order by chinesename collate Chinese_PRC_CS_ ...
- java加载资源文件
className.class.getResourceAsStream 用法: 第一: 要加载的文件和.class文件在同一目录下,例如:com.x.y 下有类Test.class ,同时有资源文件c ...
- iOS 面试题 3
0.请写出代码,用blocks来取代上例中的protocol,并比较两种方法的优势.实际应用部分?请写出代码,用blocks取代协议或回调方法 声明: #import <Foundation/F ...
- java.lang.NoClassDefFoundError: javax/xml/stream/XMLStreamException
?缺少jsr173_1.0_api.jar 包 或者jdk版本不对(包括工程和tomcat等服务器的jdk版本) 以前的一个xfire工程,今天重新导进后不能运行,修改工程的jdk版本不行,最后发现是 ...
- 网络编程之TCP
知识补充:源IP地址和目的IP地址以及源端口号和目的端口号的组合称为套接字.其用于标识客户端请求的服务器和服务. TCP编程的实现步骤:服务器端:1.通过ServletSocket创建绑定到指定客户端 ...