C# 下操作 sqlite,附加密功能,使用 microsoft.data.sqlite 或 sqlite-net

主要有三种方法,详细介绍第一种:

一、使用 Microsoft.Data.Sqlite,SQLitePCLRaw.bundle_e_sqlcipher

代码如下:

//nuget 引入 Microsoft.data.sqlite和SqlitePclraw.bundle_e_sqlcipher
using Microsoft.Data.Sqlite;
public static SqliteConnection conn;
 
//通过密码打开数据库,后面代码示例都省略了try...catch
try
{
    string connStr = new SqliteConnectionStringBuilder
    {
        DataSource = "D:\\testsql.db", //指定数据库位置
        Mode = SqliteOpenMode.ReadWriteCreate, //如果文件不存在则创建
        Password = "1234",
    }.ToString();
 
    if (conn != null)
    {
        conn.Dispose();
    }
    conn = new SqliteConnection(connStr);
 
    if (conn.State == System.Data.ConnectionState.Closed)
    {
        conn.Open();
 
        var command = conn.CreateCommand();
        //创建user_info表
        command.CommandText = $"CREATE table IF NOT EXISTS 'user_info' ('id'  INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, 'name' TEXT, 'address' TEXT);";
        command.ExecuteNonQuery();
    }
}
catch (Exception e)
{
}
 
 
//修改数据库密码
var command = conn.CreateCommand();
command.CommandText = "PRAGMA rekey = '12345';"; //修改密码
command.ExecuteNonQuery();
 
 
//查询语句
var command = conn.CreateCommand();
command.CommandText = "SELECT * FROM user_info WHERE id = 1 LIMIT 1;"; //可以使用LIMIT语句来限制返回的行数,在Sqlite之中仅能在Select语句之中使用
using (var reader = command.ExecuteReader())
{
    long user_id = 0;
    string user_name = string.Empty;
    string address = string.Empty;
 
    while (reader.Read())
    {
        //以下展示不同方法获取数据
 
        for (int i = 0; i < reader.FieldCount; i++) //循环获取字段内容,也可以直接指定id获取
        {
            if (reader.IsDBNull(i))
            {
                continue;//如果是空则跳过
            }
            string column_name = reader.GetName(i); //获取列名
            //判断列的类型
            //Console.WriteLine(reader.GetName(i) + " : " + reader.GetFieldType(i));
            /*
            if (reader.GetFieldType(i) == typeof(Int64))
            {
                long column_value = reader.GetInt64(i); //以int格式获取列中数据 sqlite之中的int是64位的
                //int column_value = reader.GetInt32(i); //如果位数不多也可以用GetInt32
            }
            else if (reader.GetFieldType(i) == typeof(string))
            {
                string column_value = reader.GetString(i); //以string格式获取列中数据
            }
            */
 
            if (column_name == "id")
            {
                user_id = reader.GetInt64(i);
            }
        }
 
        user_name = reader.GetString(reader.GetOrdinal("name"));//也可以直接通过列名来获取数据
        address = reader.GetString(2); //可以直接通过列的索引来获取数据
    }
 
    this.Dispatcher.BeginInvoke(DispatcherPriority.Send, new System.Action(() => {
        tTip.Text = $"user_id : {user_id} user_name : {user_name} address : {address}"; //刷新到ui
    }));
}
 
 
 
//使用REPLACE和INSERT插入记录
var command = conn.CreateCommand();
string address = "somewhere";
address = address.Replace("'", "''");//将单引号转义 因为sql语句中的字符串需要用单引号括起来
 
string name = "somebody";
//将单引号转义 因为sql语句中的字符串需要用单引号括起来
name = name.Replace("'", "''");
 
//command.CommandText = $"INSERT INTO user_info (id, name, address) VALUES (1, '{name}', '{address}');"; //插入一条数据
//command.CommandText = $"INSERT INTO user_info (name, address) VALUES ('{name}', '{address}');"; //id如果是自增则可以不用指定数值
//command.CommandText = $"INSERT INTO user_info (id, name, address) VALUES (1, '{name}', '{address}');"; //如果values齐全,字段名可以省略,但是顺序要和表中一致
 
//REPLACE INTO 类似INSERT,但会检查键值(此处为id),如果存在键值相同的记录,就先删除再插入
command.CommandText = $"REPLACE INTO user_info VALUES (1, '{name}', '{address}');";
//command.CommandText = $"REPLACE INTO user_info (name, address) VALUES ('{name}', '{address}');"; //不指定键值的话,则会一直往表里插入,完全等效于INSERT,请注意不要乱用
 
 
//UPDATE语句用于更新数据
var command = conn.CreateCommand();
command.CommandText = $"UPDATE user_info SET name = '{name}', address = '{address}' WHERE id = 1;"; //更新数据
command.ExecuteNonQuery();//执行无返回结果的sql语句
 
 
 
//删除语句
var command = conn.CreateCommand();
command.CommandText = $"DELETE FROM user_info WHERE id = {id};";
command.ExecuteNonQuery();
 
 
///获取表的所有字段
var command = conn.CreateCommand();
command.CommandText = "PRAGMA table_info(user_info);"; //获取表的信息
using (var reader = command.ExecuteReader())
{
    while (reader.Read())
    {
        for (int i = 0; i < reader.FieldCount; i++)
        {
            string name = reader.GetName(i); //获取列名
        }
    }
}
 
 
//关闭数据库连接
if (conn != null)
{
    conn.Close();
    conn.Dispose();
}

使用 navicat 打开加密 sqlite 数据库的方法:

  1. 打开 navicat 安装目录,找到 sqlite3.dll,将该文件备份。
  2. 通过 nuget 安装完 SqlitePclraw.bundle_e_sqlcipher,去项目 /bin/debug/runtimes 目录,根据当前系统进入 win-x86 或 win-x64 下 native 目录,找到 e_sqlcipher.dll
  3. 将 e_sqlcipher.dll 复制到 navicat 安装目录并改名 sqlite3.dll
  4. 运行 navicat,新建连接 ->Sqlite-> 现有的数据库文件,选择选项卡 “高级”,勾选 “已加密”,输入密码,点左下方 “测试连接”,确认无误后点 “确定”,即可打开加密的 sqlite 数据库

二、使用 sqlite-net

简单几段代码演示一下,更详细说明可以参考 sqlite-net 官网

//nuget之中添加 sqlite-net-sqlcipher 这个是有加密支持的 修改密码语句类似上面
 
public class user_info
{
    [PrimaryKey, AutoIncrement]
    public int id { get; set; }
    public string name { get; set; }
    public string address { get; set; }
}
 
SQLiteAsyncConnection connAsync;
//SQLiteConnection conn;  //也可以使用同步版的SQLiteConnection
 
try
{
    //db文件路径和密码,注意没有Data Source=    文件如不存在会自动创建
    var options = new SQLiteConnectionString(@"d://testsql.db", true, key: "1234");
 
    connAsync = new SQLiteAsyncConnection(options);
    connAsync.CreateTableAsync<user_info>(); //创建user_info表 异步版执行方法
 
    //同步版执行方法
    //conn = new SQLiteConnection(options);
    //conn.CreateTable<user_info>(); //创建user_info表
}
catch
{
}
 
connAsync.InsertAsync(new user_info { name = "张三", address = "北京" }); //插入一条数据
 
var count = await connAsync.ExecuteScalarAsync<int>("select count(*) from user_info"); //查询表中数据

三、使用 System.Data.Sqlite 方法类似,但是加密模块要收费(略)

posted @   太空城游客  阅读(520)  评论(1编辑  收藏  举报
相关博文:
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
点击右上角即可分享
微信分享提示