【原创】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”或它的某一个依赖项.试图加载格式不正确的程序.
随机推荐
- HTTP协议之 简易浏览器(3)--转载
简单的说,今天的全部工作就是 我的目的只有两个 1.加深对http协议的理解 2.深化对B/S结构的认识. 代码 1 /* 2 这个程序把主机地址写死了, 3 想更像的话,可以在加个输入.然后根据 ...
- ionic 图片轮播问题
1.使用ion-slide可以实现图片轮播,但是如果在html中仅仅增加ion-slide是远远不够的,会出现两个问题: (注:使用的是angularjs.首先需要在,js文件中注入:$ionicSl ...
- SQL Server 模式和名称解析
模式实际上是名称空间,因此在SQL Serve中调用数据库对象时,一定要设置对象引用的环境.每个用户都被赋予了一个默认模式,在用户登录SQL Server并凋用数据库对象时,这个默认模式就是对象引用方 ...
- .Net Memory -- Windbg基本命令
命令 解释 .cls 清空命令窗口屏幕 .load dllfullpath 加载debugger扩展dll如SOS sosex psscor. .loadby dll moduleName 加载deb ...
- Python学习笔记2(控制语句)
1.if条件语句 if(表达式): 语句1 else: 语句2 2.if...elif...else判断语句 if(表达式1):语句1 elif(表达式2):语句2 ... elif(表达式n):语句 ...
- poj 3959 Alignment of Code <vector>“字符串”
Description You are working in a team that writes Incredibly Customizable Programming Codewriter (IC ...
- x^2+y^2=N的整数解?
本文系转载:http://blog.sina.com.cn/s/blog_a661ecd50101cv41.html 我们先研究这个问题的一部分:哪些素数是两平方数之和?为什么我们先研究素数,有个很重 ...
- cmd下操作mysql
将mysql 安装目录下 的bin 添加到 windows 环境变量 步骤: 我的电脑 ->高级->环境变量->path->选择一个用户-> ...
- Android中的消息机制:Handler消息传递机制
参考<疯狂android讲义>第2版3.5 P214 一.背景 出于性能优化考虑,Android的UI操作并不是线程安全的,这意味着如果有多个线程并发操作UI组件,可能导致线程安全问题.为 ...
- android listview Caused by: java.lang.ArrayIndexOutOfBoundsException: length=3; index=3
android listview 适配器在多种类型viewType报错: Caused by: java.lang.ArrayIndexOutOfBoundsException: length=3; ...