C# & SQLite 1007000
使用 SQLite 嵌入式数据库的 .NET 项目
引言
本文讨论如何使用 SQLite 嵌入式数据库构建 VS2010 项目。
背景
首先,您需要获取一些文件并安装一些必要的软件包。
- SQLite ADO.NET 提供程序 http://sqlite.phxsoftware.com
- SQLite 管理器 http://sqliteadmin.orbmu2k.de
SQLite ADO.NET 提供程序
我将此工具安装在 "C:\Temp" 文件中,并且选择不注册 DLL 文件。 这是因为我只需要在我的项目中包含主 DLL。
SQLite 管理工具
我选择了此工具的完整安装,我对结果感到满意。
Using the Code
SQLite
首先,我们使用 SQLite 管理工具创建一个名为 "Contact.3db" 的 SQLite 数据库。
我添加了一个名为 "Contact
" 的表,其中包含一些字段,并插入了一些数据记录以供使用....
CREATE TABLE [Contact](
[contact_id] INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
[FirstName] vARCHAR(50) NULL,
[LastName] vARCHAR(50) NULL )
VS 2O1O & .NET 4.0
接下来,我创建了一个名为 "Contact
" 的 VS 2010 项目,并添加了一些文件夹和文件。 添加一个文件夹 [Database] 并插入一个现有项目 [Contact.3db
] 数据库。 将属性“复制到输出目录”更改为“始终复制”。
接下来,我将必要的 SQLite DLL 添加到我的项目中。
- System.Data.SQLite.dll
- 更改属性“复制到输出目录”=>“始终复制”
- SQLite.Interop.dll
- 更改属性“复制到输出目录”=>“始终复制”
备注
必须将这两个文件 [System.Data.SQLite.dll, SQLite.Interop.dll] 包含到您的项目中
就在您的项目的根元素下。 因此,当您在第三方 PC 上安装时,它们将
与 *.exe 文件位于同一目录中。
[参见图片。解决方案资源管理器]
接下来,我添加了一个名为“Classes”的文件夹,并创建了两个处理所有数据库事务的类。[dBFunctions.cs, dBHelper.cs]
[参见图片。解决方案资源管理器]
接下来,我添加了一个名为“Forms”的文件夹,并创建了一些窗体来处理用户交互/界面。
[ContactList.cs, BaseContact.cs, NewContact.cs, EditContact.cs, DeleteContact.cs]。
这包括我项目中的文件。
您可以从此处下载源代码。
小提示
在下载中,我包含了“Debug”目录,因为这是我存储数据库的位置,这是本文的主题,您可以在第一个类“dBFunctions
”中看到。
数据库类
在 [dBFunction
] 类中,我存储了连接字符串和数据库的位置,该数据库位于“Debug”目录中。
通过将 connectionstring
放在一个单独的类中,我可以通过仅使用一个实例
的 connectionString
[dBFunctions
] 类来创建 [dBHelper
] 类的不同实例。
结论
- 使用 [
dBFunctions
] 类连接到数据库 - 使用 [
dBHelper
] 类连接到数据库中的表
通过这两个类,可以处理与数据库的所有交互。
dBFunctions.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
namespace Kribo.Class
{
class dBFunctions
{
public static string ConnectionStringSQLite
{
get
{
string database =
AppDomain.CurrentDomain.BaseDirectory + "\\Database\\Contact.s3db";
string connectionString =
@"Data Source=" + Path.GetFullPath(database);
return connectionString;
}
}
}
}
dBHelper.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Data.SQLite;
namespace Kribo.Class
{
class dBHelper
{
// Declartion internal variables
private SQLiteConnection m_connection = null;
private string m_connectionString = "";
private SQLiteDataAdapter m_dataAdapter = null;
private DataSet m_dataSet = null;
private string m_fieldNameID = "";
// The DataSet is filled with the methode LoadDataSet
public DataSet DataSet
{
get { return m_dataSet; }
}
// Constructor -> ConnectionString is required
public dBHelper(string connectionString)
{
m_connectionString = connectionString;
}
// Load the DataSet
public bool Load(string commandText, string fieldNameID)
{
// Save the variables
m_fieldNameID = fieldNameID;
try
{
// Open de connectie
m_connection = new SQLiteConnection(m_connectionString);
m_connection.Open();
// Make a DataAdapter
m_dataAdapter = new SQLiteDataAdapter(commandText, m_connection);
// Link a eventhandler to the RowUpdated-event of the DataAdapter
//m_dataAdapter.RowUpdated += new SqlRowUpdatedEventHandler
(m_dataAdapter_RowUpdated);
m_dataAdapter.RowUpdated += m_dataAdapter_RowUpdated;
m_dataSet = new DataSet();
// For a save --> create Commands
if (!string.IsNullOrEmpty(fieldNameID))
{
SQLiteCommandBuilder commandBuilder =
new SQLiteCommandBuilder(m_dataAdapter);
m_dataAdapter.InsertCommand = commandBuilder.GetInsertCommand();
m_dataAdapter.DeleteCommand = commandBuilder.GetDeleteCommand();
m_dataAdapter.UpdateCommand = commandBuilder.GetUpdateCommand();
}
// Fill the DataSet
m_dataAdapter.Fill(m_dataSet);
// We're here, OK!
return true;
}
catch (Exception)
{
throw;
}
finally
{
// Always close
m_connection.Close();
}
}
// Load the DataSet
public bool Load(string commandText)
{
return Load(commandText, "");
}
// Save the DataSet
public bool Save()
{
// Save is only posible if ID is known
if (m_fieldNameID.Trim().Length == 0)
{
return false;
}
try
{
// Open the connection
m_connection.Open();
// Save the DataRow. This triggers an event OnRowUpdated
m_dataAdapter.Update(m_dataSet);
// We here, OK!
return true;
}
catch (Exception)
{
throw;
}
finally
{
// Close
m_connection.Close();
}
}
// Save is only posible if ID is known
void m_dataAdapter_RowUpdated(object sender,
System.Data.Common.RowUpdatedEventArgs e)
{
// The (just receaved?) ID is only interesting with a new record
if (e.StatementType == StatementType.Insert)
{
// Determin the just receaved ID
SQLiteCommand command = new SQLiteCommand
("SELECT last_insert_rowid() AS ID", m_connection);
// Get the new ID and Save in the according field
object newID = command.ExecuteScalar();
// BIf errors then no ID --> thus testing required
if (newID == System.DBNull.Value == false)
{
// Put the ID in the DataRow
e.Row[m_fieldNameID] = Convert.ToInt32(nieuweID);
}
}
}
}
}
用户交互
接下来是我创建的表单...
“ContactList
”表单和我忘记修改的标题“cc
”是此应用程序演示的主表单。 它有一个toolMenuStrip
,dataGridView
和 contextMenuStrip
。 contextMenuStrip
链接到 datGridView
。
接下来,我创建了负责对数据库进行所有修改的表单,即插入、编辑和删除表单。 这些表单是基于我的基本表单“BaseContact
”的继承表单。 所以一个 OOP 的小例子。 为了实现这一点,必须通过更改一些方法的安全策略来更改 [BaseContact.Designer.cs] 类。
结论
有关编码详细信息,最好从此处下载源代码。
历史
- 2011 年 5 月 3 日:初始发布