C# 封装 System.Data.SQLite
参考1:
关于如何使用System.Data.SQLite的入门:
http://www.dreamincode.net/forums/topic/157830-using-sqlite-with-c%23/
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SQLite;
using System.Globalization;
using System.Linq;
using System.Windows.Forms; namespace Simple_Disk_Catalog
{
public class SQLiteDatabase
{
String DBConnection; private readonly SQLiteTransaction _sqLiteTransaction; private readonly SQLiteConnection _sqLiteConnection; private readonly bool _transaction; /// <summary>
/// Default Constructor for SQLiteDatabase Class.
/// </summary>
/// <param name="transaction">Allow programmers to insert, update and delete values in one transaction</param>
public SQLiteDatabase(bool transaction = false)
{
_transaction = transaction;
DBConnection = "Data Source=recipes.s3db";
if (transaction)
{
_sqLiteConnection = new SQLiteConnection(DBConnection);
_sqLiteConnection.Open();
_sqLiteTransaction = _sqLiteConnection.BeginTransaction();
}
} /// <summary>
/// Single Param Constructor for specifying the DB file.
/// </summary>
/// <param name="inputFile">The File containing the DB</param>
public SQLiteDatabase(String inputFile)
{
DBConnection = String.Format("Data Source={0}", inputFile);
} /// <summary>
/// Commit transaction to the database.
/// </summary>
public void CommitTransaction()
{
_sqLiteTransaction.Commit();
_sqLiteTransaction.Dispose();
_sqLiteConnection.Close();
_sqLiteConnection.Dispose();
} /// <summary>
/// Single Param Constructor for specifying advanced connection options.
/// </summary>
/// <param name="connectionOpts">A dictionary containing all desired options and their values</param>
public SQLiteDatabase(Dictionary<String, String> connectionOpts)
{
String str = connectionOpts.Aggregate("", (current, row) => current + String.Format("{0}={1}; ", row.Key, row.Value));
str = str.Trim().Substring(, str.Length - );
DBConnection = str;
} /// <summary>
/// Allows the programmer to create new database file.
/// </summary>
/// <param name="filePath">Full path of a new database file.</param>
/// <returns>true or false to represent success or failure.</returns>
public static bool CreateDB(string filePath)
{
try
{
SQLiteConnection.CreateFile(filePath);
return true;
}
catch (Exception e)
{
MessageBox.Show(e.Message, e.GetType().ToString(), MessageBoxButtons.OK, MessageBoxIcon.Error);
return false;
}
} /// <summary>
/// Allows the programmer to run a query against the Database.
/// </summary>
/// <param name="sql">The SQL to run</param>
/// <param name="allowDBNullColumns">Allow null value for columns in this collection.</param>
/// <returns>A DataTable containing the result set.</returns>
public DataTable GetDataTable(string sql, IEnumerable<string> allowDBNullColumns = null)
{
var dt = new DataTable();
if (allowDBNullColumns != null)
foreach (var s in allowDBNullColumns)
{
dt.Columns.Add(s);
dt.Columns[s].AllowDBNull = true;
}
try
{
var cnn = new SQLiteConnection(DBConnection);
cnn.Open();
var mycommand = new SQLiteCommand(cnn) {CommandText = sql};
var reader = mycommand.ExecuteReader();
dt.Load(reader);
reader.Close();
cnn.Close();
}
catch (Exception e)
{
throw new Exception(e.Message);
}
return dt;
} public string RetrieveOriginal(string value)
{
return
value.Replace("&", "&").Replace("<", "<").Replace(">", "<").Replace(""", "\"").Replace(
"'", "'");
} /// <summary>
/// Allows the programmer to interact with the database for purposes other than a query.
/// </summary>
/// <param name="sql">The SQL to be run.</param>
/// <returns>An Integer containing the number of rows updated.</returns>
public int ExecuteNonQuery(string sql)
{
if (!_transaction)
{
var cnn = new SQLiteConnection(DBConnection);
cnn.Open();
var mycommand = new SQLiteCommand(cnn) {CommandText = sql};
var rowsUpdated = mycommand.ExecuteNonQuery();
cnn.Close();
return rowsUpdated;
}
else
{
var mycommand = new SQLiteCommand(_sqLiteConnection) { CommandText = sql };
return mycommand.ExecuteNonQuery();
}
} /// <summary>
/// Allows the programmer to retrieve single items from the DB.
/// </summary>
/// <param name="sql">The query to run.</param>
/// <returns>A string.</returns>
public string ExecuteScalar(string sql)
{
if (!_transaction)
{
var cnn = new SQLiteConnection(DBConnection);
cnn.Open();
var mycommand = new SQLiteCommand(cnn) {CommandText = sql};
var value = mycommand.ExecuteScalar();
cnn.Close();
return value != null ? value.ToString() : "";
}
else
{
var sqLiteCommand = new SQLiteCommand(_sqLiteConnection) { CommandText = sql };
var value = sqLiteCommand.ExecuteScalar();
return value != null ? value.ToString() : "";
}
} /// <summary>
/// Allows the programmer to easily update rows in the DB.
/// </summary>
/// <param name="tableName">The table to update.</param>
/// <param name="data">A dictionary containing Column names and their new values.</param>
/// <param name="where">The where clause for the update statement.</param>
/// <returns>A boolean true or false to signify success or failure.</returns>
public bool Update(String tableName, Dictionary<String, String> data, String where)
{
String vals = "";
Boolean returnCode = true;
if (data.Count >= )
{
vals = data.Aggregate(vals, (current, val) => current + String.Format(" {0} = '{1}',", val.Key.ToString(CultureInfo.InvariantCulture), val.Value.ToString(CultureInfo.InvariantCulture)));
vals = vals.Substring(, vals.Length - );
}
try
{
ExecuteNonQuery(String.Format("update {0} set {1} where {2};", tableName, vals, where));
}
catch
{
returnCode = false;
}
return returnCode;
} /// <summary>
/// Allows the programmer to easily delete rows from the DB.
/// </summary>
/// <param name="tableName">The table from which to delete.</param>
/// <param name="where">The where clause for the delete.</param>
/// <returns>A boolean true or false to signify success or failure.</returns>
public bool Delete(String tableName, String where)
{
Boolean returnCode = true;
try
{
ExecuteNonQuery(String.Format("delete from {0} where {1};", tableName, where));
}
catch (Exception fail)
{
MessageBox.Show(fail.Message, fail.GetType().ToString(), MessageBoxButtons.OK, MessageBoxIcon.Error);
returnCode = false;
}
return returnCode;
} /// <summary>
/// Allows the programmer to easily insert into the DB
/// </summary>
/// <param name="tableName">The table into which we insert the data.</param>
/// <param name="data">A dictionary containing the column names and data for the insert.</param>
/// <returns>returns last inserted row id if it's value is zero than it means failure.</returns>
public long Insert(String tableName, Dictionary<String, String> data)
{
String columns = "";
String values = "";
String value;
foreach (KeyValuePair<String, String> val in data)
{
columns += String.Format(" {0},", val.Key.ToString(CultureInfo.InvariantCulture));
values += String.Format(" '{0}',", val.Value);
}
columns = columns.Substring(, columns.Length - );
values = values.Substring(, values.Length - );
try
{
if (!_transaction)
{
var cnn = new SQLiteConnection(DBConnection);
cnn.Open();
var sqLiteCommand = new SQLiteCommand(cnn)
{
CommandText =
String.Format("insert into {0}({1}) values({2});", tableName, columns,
values)
};
sqLiteCommand.ExecuteNonQuery();
sqLiteCommand = new SQLiteCommand(cnn) { CommandText = "SELECT last_insert_rowid()" };
value = sqLiteCommand.ExecuteScalar().ToString();
}
else
{
ExecuteNonQuery(String.Format("insert into {0}({1}) values({2});", tableName, columns, values));
value = ExecuteScalar("SELECT last_insert_rowid()");
}
}
catch (Exception fail)
{
MessageBox.Show(fail.Message, fail.GetType().ToString(), MessageBoxButtons.OK, MessageBoxIcon.Error);
return ;
}
return long.Parse(value);
} /// <summary>
/// Allows the programmer to easily delete all data from the DB.
/// </summary>
/// <returns>A boolean true or false to signify success or failure.</returns>
public bool ClearDB()
{
try
{
var tables = GetDataTable("select NAME from SQLITE_MASTER where type='table' order by NAME;");
foreach (DataRow table in tables.Rows)
{
ClearTable(table["NAME"].ToString());
}
return true;
}
catch
{
return false;
}
} /// <summary>
/// Allows the user to easily clear all data from a specific table.
/// </summary>
/// <param name="table">The name of the table to clear.</param>
/// <returns>A boolean true or false to signify success or failure.</returns>
public bool ClearTable(String table)
{
try
{
ExecuteNonQuery(String.Format("delete from {0};", table));
return true;
}
catch
{
return false;
}
} /// <summary>
/// Allows the user to easily reduce size of database.
/// </summary>
/// <returns>A boolean true or false to signify success or failure.</returns>
public bool CompactDB()
{
try
{
ExecuteNonQuery("Vacuum;");
return true;
}
catch (Exception)
{
return false;
}
}
}
}
参考2:
关于如何正确使用System.Data.SQLite提高性能
SQLite .NET performance, how to speed up things?
You definitely need a transaction. If you don't, SQLite starts its own transaction for every insert command so you're effectively doing 86000 transactions as is.
It looks you're also opening and closing the connection each time, along with resetting the CommandText each time. This is unnecessary and doubtless slowing you down, it'll go much faster if you:
- Open the connection once
- Build the command once , adding the parameters to it once.
- Start the transaction
- Loop through, changing the parameter values only before calling ExecuteNonQuery
- Commit the transaction.
- Close the connection.
I think you could reduce your 20 minutes down to just a few seconds this way.
Edit: this is what I mean:
public void InsertItems()
{
SQLiteConnection connection = new SQLiteConnection(SomeConnectionString);
SQLiteCommand command = connection.CreateCommand();
SQLiteTransaction transaction = connection.BeginTransaction(); command.CommandText = "INSERT OR IGNORE INTO Result "
+ "(RunTag, TopicId, DocumentNumber, Rank, Score) " +
"VALUES (@RunTag, @TopicId, @DocumentNumber, @Rank, @Score)"; command.Parameters.AddWithValue("@RunTag", "");
command.Parameters.AddWithValue("@TopicId", "");
command.Parameters.AddWithValue("@DocumentNumber", "");
command.Parameters.AddWithValue("@Rank", "");
command.Parameters.AddWithValue("@Score", ""); foreach ( /* item to loop through and add to db */ )
{
InsertResultItem(runTag, topicId, documentNumber, rank, score, command);
} transaction.Commit();
command.Dispose();
connection.Dispose();
} public int InsertResultItem(string runTag, int topicId, string documentNumber, int rank, double score, SQLiteCommand command)
{
command.Parameters["@RunTag"].Value = runTag;
command.Parameters["@TopicId"].Value = topicId;
command.Parameters["@DocumentNumber"].Value = documentNumber;
command.Parameters["@Rank"].Value = rank;
command.Parameters["@Score"].Value = score;
return command.ExecuteNonQuery();
}
It only uses one connection, one transaction and one command, so all you're changing is the parameter values each time.
我自己实现的一个简易版本:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data.SQLite; namespace Utility
{
/*Multithread safety: No!*/
public class SQLiteDB
{
private SQLiteConnection m_db_conn;
private SQLiteTransaction m_transaction;
private bool m_is_transaction;
private SQLiteCommand m_transaction_cmd; public SQLiteDB()
{
m_is_transaction = false;
} public SQLiteDB(string db_path)
{
m_is_transaction = false;
m_db_conn = new SQLiteConnection(string.Format("Data Source={0}", db_path));
m_db_conn.Open();
}
public void Open(string db_path)
{
m_db_conn = new SQLiteConnection(string.Format("Data Source={0}", db_path));
m_db_conn.Open();
}
public void Close()
{
if (m_db_conn.State != System.Data.ConnectionState.Closed)
{
m_db_conn.Close();
m_db_conn.Dispose();
}
if (null != m_transaction_cmd)
{
m_transaction_cmd.Dispose();
}
} public void BeginTransaction()
{
m_is_transaction = true;
m_transaction_cmd = m_db_conn.CreateCommand();
m_transaction = m_db_conn.BeginTransaction();
} public void Commit()
{
if (m_is_transaction)
{
m_transaction.Commit();
m_transaction_cmd.Dispose();
m_is_transaction = false;
}
} public void Rollback()
{
if (m_is_transaction)
{
m_transaction.Rollback();
m_transaction_cmd.Dispose();
m_is_transaction = false;
}
} public int ExecuteNonQuery(string non_query_sql)
{
if (!m_is_transaction)
{
SQLiteCommand sql_cmd = new SQLiteCommand(m_db_conn);
sql_cmd.CommandText = non_query_sql;
return sql_cmd.ExecuteNonQuery();
}
else
{
m_transaction_cmd.CommandText = non_query_sql;
return m_transaction_cmd.ExecuteNonQuery();
}
}
}
}
C# 封装 System.Data.SQLite的更多相关文章
- System.Data.SQLite数据库简介
SQLite介绍 在介绍System.Data.SQLite之前需要介绍一下SQLite,SQLite是一个类似于Access的单机版数据库管理系统,它将所有数据库的定义(包括定义.表.索引和数据本身 ...
- SQLite 之 C#版 System.Data.SQLite 使用
简介 SQLite简介 SQLite,是一款轻型的关系型数据库.它的设计目标是嵌入式. 它能够支持Windows/Linux/Unix等等主流的操作系统,同时能够跟很多程序语言相结合,比如 C++.C ...
- 启用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.典型的是是版 ...
随机推荐
- iframe 重新加载闪过白块问题
在使用iframe时,iframe背景为白块,刷新时也会闪过白块.如果刷新时间长,就会一直出现白块,让人很烦恼,通过网上搜资料,测试最终解决方法如下所示,注意主要针对IE浏览器测试. 一.iframe ...
- $ cd `dirname $0` 和PWD%/* shell变量的一些特殊用法
在命令行状态下单纯执行 $ cd `dirname $0` 是毫无意义的.因为他返回当前路径的".". $0:当前Shell程序的文件名dirname $0,获取当前Shell程序 ...
- USB驱动开发
1.usb特点 2.usb class 3.
- AngularJS中serivce,factory,provider的区别
一.service引导 刚开始学习Angular的时候,经常被误解和被初学者问到的组件是 service(), factory(), 和 provide()这几个方法之间的差别.This is whe ...
- spring:ContextLoaderListener接口
在启动Web容器时,自动装配Spring applicationContext.xml的配置信息. 因为它实现了ServletContextListener这个接口,在web.xml配置这个监听器,启 ...
- Exception和IOException之间的使用区别
Exception和IOException之间的使用区别 先看一段代码.这段代码来自<深入剖析tomcat> public void await() { // 创建ServerSock ...
- 使用微软的(how-old.net)构建智能门店管理系统
现在是大数据时代,每个企业都要对自己的客户有全面的认识,这样才能最准确的分析客户,做出相应的决策.在实体的门店中,对于客户的管理还是比较低级,很多客户对于企业来说是哑终端,即对于企业来说,完全不知道客 ...
- I/O事件
I/O事件 最近在研究tornado和gevent,里面涉及了非阻塞I/O.在了解非阻塞I/O之前,需要先了解I/O事件 我们知道,内核有缓冲区.假设有两个进程A,B,进程B想读进程A写入的东西(即进 ...
- oracle 创建表空间详细介绍
注意点: 1.如果在PL/SQL 等工具里打开的话,直接修改下面的代码中[斜体加粗部分]执行 2.确保路径存在,比如[D:\oracle\oradata\Oracle9i\]也就是你要保存文件的路径存 ...
- javascript 事件设计模式
http://plkong.iteye.com/blog/213543 1. 事件设计概述 事件机制可以是程序逻辑更加清晰可见,在JavaScript中很多对象都有自己的事件,如:button有onc ...