当前位置: 首页 > news >正文

C#项目中添加本地数据库——SQLite

C#项目中添加本地数据库

我们在日常开发工作中,不可避免地使用到数据库,这篇文章将介绍一个C# 轻量 ORM 库——SQLite.主要的概念介绍这里就不多说了,文章以干货为主。

1. 开发工具

Microsoft Visual Studio Community 2022 (64 位) - Current
版本 17.14.21 (November 2025)

2. 安装对应的 NuGet 包

1)在 Visual Studio 中:右键项目 → 管理 NuGet 包;
2)搜索并安装:sqlite-net-pcl.

3. 建立文件夹

建议是新建文件夹,将有关数据库的内容保存在一起,这样便于管理,以下是我的文件结构,可以用于参考。

其中:DatabaseManager.cs存放的是数据库的管理操作;UserRepository.cs存放的是对User数据表的管理操作;User.cs存放的是User数据表的结构。

4. 建立数据表

建立数据表的结构,也就是Model.以下是我的User.cs文件的内容,可以作为参考。

usingSQLite;namespaceMy.DatabaseModel{/// <summary>/// 用户表/// </summary>[Table("User")]publicclassUser{[PrimaryKey,AutoIncrement][Column("id")]publicintId{get;set;}[Column("userId")]publicstringDoctorId{get;set;}[Column("avatar")]publicstringAvatar{get;set;}[Column("name")]publicstringName{get;set;}}}

1)其中 [PrimaryKey, AutoIncrement]表示id是该表的主键,数值自增。
2)userId建议保持唯一性,可以根据id变化,以下是参考,根据id修改后一定要记得更新。

// 1️ 插入 UserDb.Insert(user);// 2️ 生成 PatientIduser.UserId="U"+(10000+user.Id);// 3️ 更新 UserDb.Update(user);

5. 建立数据库

数据库的操作基本上是初始化和销毁两个操作而已。

usingMy.DatabaseModel;usingSQLite;namespaceMy.Database{publicclassDatabaseManager{privatestaticSQLiteConnectiondb;privatestaticstringdbPath=Path.Combine(AppDomain.CurrentDomain.BaseDirectory,"myDatabase.db");publicstaticSQLiteConnectionDB{get{if(db==null){Init();}returndb;}}publicstaticvoidInit(){// 1 判断数据库是否存在booldbExists=File.Exists(dbPath);// 2 创建连接db=newSQLiteConnection(dbPath);if(!dbExists){Console.WriteLine("数据库不存在,创建数据库...");// 自动创建表// 用户表db.CreateTable<User>();}Console.WriteLine("数据库初始化完成");}/// <summary>/// 销毁数据库/// </summary>publicstaticvoidDestroyDatabase(){try{//1 关闭数据库连接if(db!=null){db.Close();db.Dispose();db=null;}//2 删除数据库文件if(File.Exists(dbPath)){File.Delete(dbPath);Console.WriteLine("数据库已销毁");}}catch(Exceptionex){Console.WriteLine("删除数据库失败: "+ex.Message);}}/// <summary>/// 重置数据库/// </summary>publicstaticvoidResetDatabase(){DestroyDatabase();Init();}}}

这里注意,销毁数据库时一定要先关闭数据库连接,再删除数据库文件。
private static string dbPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "myDatabase.db");就是创建数据库文件,文件名为“myDatabase.db”.文件名可以自定义的,建议根据自己的需求更换具有标识性的文件名,建议以Database结尾。

6. 增加对数据表的操作

我将对数据表的操作以表为单位建立了文件——UserRepository.cs.以下是我的文件内容,可以作为参考。

usingMy.DatabaseModel;usingSQLite;namespaceRTLAB_MMDS.Database{publicclassUserRepository{privatestaticSQLiteConnectionDb=>DatabaseManager.DB;/// <summary>/// 插入数据/// </summary>/// <param name="user"></param>/// <returns></returns>publicUserInsertUser(Useruser){Db.Insert(user);returnuser;}/// <summary>/// 获取全部数据/// </summary>/// <returns></returns>publicList<User>GetAllUsers(){returnDb.Table<User>().ToList();}/// <summary>/// 根据用户id获取数据/// </summary>/// <param name="userId"></param>/// <returns></returns>publicUserGetUserByUserId(stringuserId){returnDb.Table<User>().FirstOrDefault(d=>d.UserId==userId);}/// <summary>/// 根据用户id删除患者/// <param name="userId"></param>/// </summary>publicvoidDelete(stringuserId){Db.Table<User>().Delete(d=>d.UserId==userId);}/// <summary>/// 更新用户/// </summary>publicUserUpdate(Useruser){Db.Update(user);returnuser;}}}

这种不涉及外键连接和多表组合的数据库操作是比较简单的,这里写的也不是很全,但是基本逻辑是这样的,相对复杂的等会放后面单独讲。
还有一个点要注意的是我基本上每一个都写了return,实际根据项目情况写就好,我这里是为了下面的操作示例写的而已。

7. 数据表的操作示例

下面就给一个简单的用户表增删改的操作示例。

privatevoidexample(){//初始化数据库DatabaseManager.Init();UserRepositoryrepo=newUserRepository();//创建用户Useruser1=newUser{UserId="123",Avatar="",Name="张三",};//插入user1=repo.InsertUser(user1);Console.WriteLine("创建用户成功:"+user1.Name);// 查找Useruser2=repo.GetUserByUserId(user1.UserId);Console.WriteLine("查找用户成功:"+user2.Name);// 修改user2.Name="李四";Useruser3=repo.Update(user2);Console.WriteLine("修改用户成功:"+user3.Name);// 删除repo.Delete(user3);Console.WriteLine("删除用户成功");}

一定要初始化数据库,否则一切操作白搭,建议在Program.cs文件中就初始化。
好了,以上的基本内容就讲完了。每次总结的时候都觉得当初摸索的自己像个傻子,囧。

下面说一下组合表的事情吧。

数据库通常不会只有像上面User这样简单的表,一般可能还得存点别的结构,而在C#中又不给直接存什么List<string>;,还有数据比较大的情况下都存一张表检索又影响效率,所以,下面说一下组合的情况。

也是直接通过例子来讲解。

8. 组合表的结构

usingSQLite;namespaceMy.DatabaseModel{/// <summary>/// 患者表/// </summary>[Table("User")]publicclassUser{[PrimaryKey,AutoIncrement][Column("id")]publicintId{get;set;}[Column("userId")]publicstringDoctorId{get;set;}[Column("avatar")]publicstringAvatar{get;set;}[Column("name")]publicstringName{get;set;}[Ignore]// SQLite-Net 属性,告诉它不要映射到表publicList<Other>Others{get;set;}=newList<Other>();}/// <summary>/// 其他/// </summary>[Table("Other")]publicclassOther{[PrimaryKey,AutoIncrement][Column("id")]publicintId{get;set;}[Column("userId")]publicstringUserId{get;set;}[Column("otherName")]publicstringOtherName{get;set;}}}

1)Other也需要在初始化数据库时创建表,即在DatabaseManager.cs中添加db.CreateTable<Other>();
2)Other.UserId=User.userId,当然字段名是可以自定义的,不过建议相同,这样可读性比较高。
4)List<Other> Others;我这里存的是List,也可以存一条public Other OtherSingle{ get; set; } = new Other();如果存的OtherSingle,记得修改以下对组合表的操作。

9. 对组合表的操作

直接上代码吧,直观很重要!!!

usingMy.DatabaseModel;usingSQLite;namespaceRTLAB_MMDS.Database{publicclassUserRepository{privatestaticSQLiteConnectionDb=>DatabaseManager.DB;/// <summary>/// 插入数据/// </summary>/// <param name="user"></param>/// <returns></returns>publicUserInsertUser(Useruser){// RunInTransaction是保证数据库操作的原子性// 通俗解释就是RunInTransaction里面的代码只有两个结果,全部失败和全部成功Db.RunInTransaction(()=>{// 插入userDb.Insert(user);stringuserId=user.UserId;if(user.others!=null){foreach(varotherinuser.Others){other.UserId=userId;// 插入otherDb.Insert(other);}}});returnuser;}/// <summary>/// 获取全部数据/// </summary>/// <returns></returns>publicList<User>GetAllUsers(){varusers=Db.Table<User>().ToList();// 把 Other 表按 UserId 分组,生成一个可以快速查找的内存索引varotherLookup=Db.Table<Other>().ToList().ToLookup(p=>p.UserId);foreach(varuserinusers){// 这里就可以根据user.userId直接索引到全部数据啦user.Others=otherLookup[user.userId].ToList();}returnusers;}/// <summary>/// 根据用户id获取数据/// </summary>/// <param name="userId"></param>/// <returns></returns>publicUserGetUserByUserId(stringuserId){varuser=Db.Table<User>().FirstOrDefault(d=>d.UserId==userId);if(user==null)returnnull;user.Others=Db.Table<Other>().Where(p=>p.UserId==userId).ToList();returnuser;}/// <summary>/// 根据用户id删除患者/// <param name="userId"></param>/// </summary>publicvoidDelete(stringuserId){// 先删除子表里的数据Db.Table<Other>().Delete(a=>a.UserId==userId);// 再删除主表里的数据Db.Table<User>().Delete(d=>d.UserId==userId);}/// <summary>/// 更新用户/// </summary>publicUserUpdate(Useruser){Db.Update(user);stringuserId=user.UserId;// 删除旧OtherDb.Table<Other>().Delete(p=>p.userId==userId);// 插入新Otherif(user.Others!=null){foreach(varotherinuser.Others){other.UserId=userId;Db.Insert(other);}}returnuser;}}}

10. 插入组合表

这里就简单给一个插入的示例吧,其他操作都是相通的。

privatevoidexample(){//初始化数据库DatabaseManager.Init();UserRepositoryrepo=newUserRepository();//创建用户Useruser=newUser{UserId="123",Avatar="",Name="张三",};List<Other>others=newList<Other>();for(inti=0;i++;i<10){Otherother=newOther();other.OtherName=$"OtherName_{i}";others.Add(other);}user.Other=others;//插入user=repo.InsertUser(user);Console.WriteLine("创建用户成功:"+user.Name);}

11. 结语

总结就是,啥也不会的时候开头最难,等回顾的时候发现好像也就那样。数据库从无到有大致就是这样了。数据量大的情况下,比如存了绘图数据,有N个点的那种,也可以考虑文件存储方式,List<string>也可以考虑json存储,这就下次遇到再说吧。感谢你看完全文!比心!

http://www.jsqmd.com/news/506905/

相关文章:

  • 信创环境实战:在CtyunOS内网离线部署Dify全栈指南
  • 基于PLC技术的3x4立体车库系统设计:全自动升降横移载车板智能管理12个车位
  • GitHub_Trending/ms/MS-DOS源代码中的栈操作:函数调用的底层实现
  • RancherRuntimeHandler:配置容器运行时的自定义选项
  • 【亲测免费】 SecHex-Spoofy 使用与安装指南
  • Linux下的基本指令1
  • Java 9+项目遇到Lombok报错?教你5分钟降级JDK 1.8的完整流程(附Corretto配置)
  • 从初级到阿里P7:Web前端大厂工程师训练营全技术栈解析与进阶路径(全集)
  • GitHub汉化插件终极指南:三分钟让GitHub界面全中文
  • 亚洲美女-造相Z-Turbo效果展示:同一人物在不同季节/天气/时间背景下的连贯性生成
  • Rolldown微前端方案:基于多入口的应用集成实践
  • 车载网络攻防前线告急!CAN FD未启用Secure Boot与帧级完整性校验=裸奔——立即执行这6项加固检查清单
  • UABEAvalonia:跨平台Unity资源包管理完全指南
  • 计算机毕业设计之基于Spring Boot的高校实验室管理系统
  • Python-100-Days公共卫生:疾病传播模型与数据分析完整指南
  • 聊聊资质齐全的乌金木家具品牌工厂,长城家具口碑如何? - myqiye
  • Realistic Vision V5.1 虚拟摄影棚材质表现力测试:生成不同表面纹理的高清特写
  • 选购汽修学校服务要注意啥,乌鲁木齐市万通技工学校靠谱不 - mypinpai
  • 【Dify】从零构建工作流:OpenAPI插件、代码节点与API调用的实战解析
  • 电流反馈型运放必看:电压跟随器反馈电阻选型避坑指南(以AD811为例)
  • 工业C内存池设计必踩的5个坑:从内存碎片到线程安全,90%工程师第3个就栽了?
  • 2026年雨水收集设备加工厂性价比排名,江苏华祝优势显著 - 工业品牌热点
  • GitHub_Trending/agen/agents物联网设备接入指南:打造实时多模态AI应用的终极方案
  • OSX-KVM存储迁移终极指南:从物理机到虚拟机的完整数据转移方案
  • Medusa微服务架构:基于模块化的分布式系统设计模式
  • 基于OpenCV C#的卡尺测量距离源码,含强大视觉控件源码及测试图片
  • 用户真实声音:售后体验最好的氙灯老化试验箱品牌盘点(附实测案例) - 品牌推荐大师1
  • kohya_ss模型量化工具:GPTQ与AWQ性能对比指南
  • 【产品经理原型绘制HTML】从 IDE 到 GitHub 公网部署手册
  • 基于蒙特卡洛的电动车有序充放电研究(Matlab代码实现)