探索 .NET 9 控制台应用中的 LiteDB 异步 CRUD 操作
本文主要是使用异步方式,体验
litedb
基本的crud
操作。
LiteDB
是一款轻量级、快速且免费的 .NET NoSQL
嵌入式数据库,专为小型本地应用程序设计。它以单一数据文件的形式提供服务,支持文档存储和查询功能,适用于桌面应用、移动应用和小型 Web
应用等场景。
LiteDB
的主要特点包括:
- 无服务器的 NoSQL 文档存储:
LiteDB
是一个嵌入式数据库,无需独立服务器,数据存储在一个单一文件中,类似于SQLite
。 - 简单易用的 API:
LiteDB
提供类似MongoDB
的简单API
,支持LINQ
查询和SQL-like
命令,使得开发者可以轻松上手。 - 线程安全和 ACID 事务支持:LiteDB 支持线程安全操作和完整的
ACID
事务处理,确保数据的一致性和完整性。 - 数据恢复功能:
LiteDB
使用写前日志(WAL
)机制来保证数据恢复能力,即使在写入失败的情况下也能恢复数据。 - 跨平台支持:
LiteDB
可以在Windows、Linux 和 macOS
等多个平台上运行,具有良好的跨平台兼容性。 - 加密存储:
LiteDB
支持使用DES
或AES
加密算法对数据文件进行加密,保障数据的安全性。 - 文件和流数据存储:
LiteDB
支持存储文件和流数据,类似于MongoDB
的GridFS
功能。 - 开源免费:
LiteDB
是一个开源(MIT
)项目,任何人都可以使用和修改其代码,并且完全免费,包括商业用途。
LiteDB
的使用非常简单,可以通过 NuGet
包管理器轻松安装,并且提供了丰富的文档和示例代码帮助开发者快速上手。此外,LiteDB
还提供了一个名为 LiteDB Studio
的图形用户界面工具,方便用户管理和可视化数据库内容。
总之,LiteDB
是一款功能强大、易于使用的 NoSQL
数据库解决方案,适用于多种场景,值得开发者关注和尝试。
使用 .NET CLI
创建一个控制台应用程序,可以按照以下步骤进行:
-
安装
.NET 9 SDK
:首先,确保你已经安装了.NET 9 SDK
。你可以从官方网站下载并安装最新版本的.NET SDK
。 -
创建新的控制台应用程序:使用
dotnet new console
命令创建一个新的控制台应用程序。这个命令会生成一个包含基本结构的项目文件夹。
dotnet new console -n LiteDBExample
- 导航到项目目录:进入刚刚创建的项目目录。
cd LiteDBExample
- 运行应用程序:使用
dotnet run
命令运行应用程序。
dotnet run
基础控制台项目就创建好了,丝滑般体验;
接下来我们使用 litedb
提供的 nuget
包,进行简单的封装,构建出异步操作的 crud
方法 。
- 安装相关
nuget
包:
<Project Sdk="Microsoft.NET.Sdk"><PropertyGroup><OutputType>Exe</OutputType><TargetFramework>net9.0</TargetFramework><ImplicitUsings>enable</ImplicitUsings><Nullable>enable</Nullable></PropertyGroup><ItemGroup><PackageReference Include="LiteDB" Version="5.0.21" /><PackageReference Include="LiteDB.Async" Version="0.1.8" /><PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="9.0.0" /></ItemGroup></Project>
- 创建实体类型 :
Person
public class Person
{public Guid Id { get; set; } = Guid.NewGuid();public string Name { get; set; } = default!;public uint Age { get; set; }
}
- 定义仓储类规范:
IRepository
using LiteDB;namespace LiteDBExample.Core.Interfaces;public interface IRepository<TEntity> where TEntity : class
{Task<BsonValue> AddAsync(TEntity entity);Task<int> AddRangeAsync(IEnumerable<TEntity> entities);Task<IEnumerable<TEntity>> GetAllAsync();Task<TEntity?> GetByIdAsync(object id);Task<bool> UpdateAsync(TEntity entity);Task<int> UpdateRangeAsync(IEnumerable<TEntity> entities);Task<bool> DeleteAsync(object id);Task<int> DeleteRangeAsync(IEnumerable<object> ids);
}
- 实现
PersonDbContext
using LiteDB;
using LiteDB.Async;
using LiteDBExample.Core.Entities;namespace LiteDBExample.Data;public class PersonDbContext(string connectionString) : IDisposable
{private readonly LiteDatabaseAsync _database = new(connectionString);public Task<BsonValue> AddAsync(Person person){var collection = _database.GetCollection<Person>("people");return collection.InsertAsync(person);}public Task<int> AddRangeAsync(IEnumerable<Person> persons){var collection = _database.GetCollection<Person>("people");return collection.InsertAsync(persons);}public Task<IEnumerable<Person>> GetAllAsync(){var collection = _database.GetCollection<Person>("people");return collection.FindAllAsync();}public Task<Person?> GetByIdAsync(object id){BsonValue bsonId = new(id);var collection = _database.GetCollection<Person>("people");return collection.FindByIdAsync(bsonId);}public Task<bool> UpdateAsync(Person person){var collection = _database.GetCollection<Person>("people");return collection.UpdateAsync(person);}public Task<int> UpdateRangeAsync(IEnumerable<Person> persons){var collection = _database.GetCollection<Person>("people");return collection.UpdateAsync(persons);}public Task<bool> DeleteAsync(object id){BsonValue bsonId = new(id);var collection = _database.GetCollection<Person>("people");return collection.DeleteAsync(bsonId);}public Task<int> DeleteRangeAsync(IEnumerable<object> ids){var collection = _database.GetCollection<Person>("people");return collection.DeleteManyAsync(a => ids.Contains(a.Id));}public void Dispose(){_database.Dispose();}
}
- 定义
Person
类仓储:IPersonRepository
using LiteDBExample.Core.Entities;
using LiteDBExample.Core.Interfaces;namespace LiteDBExample.Repositories;public interface IPersonRepository : IRepository<Person>
{
}
- 实现
Person
类仓储:PersonRepository
using LiteDB;
using LiteDBExample.Core.Entities;
using LiteDBExample.Data;namespace LiteDBExample.Repositories;public class PersonRepository(PersonDbContext context) : IPersonRepository
{private readonly PersonDbContext _context = context ?? throw new ArgumentNullException(nameof(context));public Task<BsonValue> AddAsync(Person entity){return _context.AddAsync(entity);}public Task<int> AddRangeAsync(IEnumerable<Person> entities){return _context.AddRangeAsync(entities);}public Task<IEnumerable<Person>> GetAllAsync(){return _context.GetAllAsync();}public Task<Person?> GetByIdAsync(object id){return _context.GetByIdAsync(id);}public Task<bool> UpdateAsync(Person entity){return _context.UpdateAsync(entity);}public Task<int> UpdateRangeAsync(IEnumerable<Person> entities){return _context.UpdateRangeAsync(entities);}public Task<bool> DeleteAsync(object id){return _context.DeleteAsync(id);}public Task<int> DeleteRangeAsync(IEnumerable<object> ids){return _context.DeleteRangeAsync(ids);}
}
- 在
Program.cs
中应用IPersonRepository
using LiteDBExample.Core.Entities;
using LiteDBExample.Repositories;
using Microsoft.Extensions.DependencyInjection;
using LiteDBExample.Data;namespace LiteDBExample;internal class Program
{static async Task Main(string[] args){Console.WriteLine("Hello, LiteDB!");var services = new ServiceCollection();ConfigureServices(services);using var serviceProvider = services.BuildServiceProvider();var personRepository = serviceProvider.GetRequiredService<IPersonRepository>();// 多个 Personvar newPeople = new List<Person>{new Person { Name = "John Kiny", Age = 16 },new Person { Name = "John Doe", Age = 30 },new Person { Name = "Jane Smith", Age = 28 },new Person { Name = "Alice Johnson", Age = 35 }};try{Console.WriteLine("===> litedb Async Method Test");{// 添加单个 Personvar person = new Person { Name = "Alice Array", Age = 32 };var bsonId = await personRepository.AddAsync(person);Console.WriteLine($"bsonId={bsonId}");// 查询单个 Personvar queryPerson = await personRepository.GetByIdAsync(bsonId);Console.WriteLine($"guid={queryPerson.Id}, {queryPerson.Name} is {queryPerson.Age} years old.");// 更新单个 Personperson.Age += 1;person.Name = "Array";var updateCount = await personRepository.UpdateAsync(person);Console.WriteLine($"updateCount={updateCount}");// 删除单个 Personvar deleteCount = await personRepository.DeleteAsync(bsonId);Console.WriteLine($"deleteCount={deleteCount}");// 批量添加多个 Personint addRange = await personRepository.AddRangeAsync(newPeople);Console.WriteLine($"addRange={addRange}");// 查询所有 Personvar people = await personRepository.GetAllAsync();foreach (var p in people){Console.WriteLine($"guid={p.Id}, {p.Name} is {p.Age} years old.");}// 批量更新多个 Personvar updatedPeople = people.Select(p => new Person { Id = p.Id, Name = p.Name, Age = p.Age + 1 });int updateRows = await personRepository.UpdateRangeAsync(updatedPeople);Console.WriteLine($"updateRows={updateRows}");// 批量删除多个 Personvar idsToDelete = new List<object>();foreach (var item in people.Select(p => p.Id)){idsToDelete.Add(item);};var ids = idsToDelete.AsEnumerable();int deleteRows = await personRepository.DeleteRangeAsync(ids);Console.WriteLine($"deleteRows={deleteRows}");}Console.ReadLine();}catch (Exception ex){Console.WriteLine($"An error occurred: {ex.Message}");}}private static void ConfigureServices(IServiceCollection services){services.AddScoped<IPersonRepository, PersonRepository>();services.AddScoped<PersonDbContext>(provider => new PersonDbContext("filename=litedb_example.db"));}
}
- 运行应用:
dotnet run
- 使用
LiteDB.Studio
工具查看litedb
数据;
当批量添加数据的时候,查看数据信息如下:
Grid
查看
Text
查看
从上图中可以看到 litedb_example.db
文件非常轻量,大概 30kb
左右;
相关文章:

探索 .NET 9 控制台应用中的 LiteDB 异步 CRUD 操作
本文主要是使用异步方式,体验 litedb 基本的 crud 操作。 LiteDB 是一款轻量级、快速且免费的 .NET NoSQL 嵌入式数据库,专为小型本地应用程序设计。它以单一数据文件的形式提供服务,支持文档存储和查询功能,适用于桌面应用、移动…...
《进程隔离机制:C++多进程编程安全的坚固堡垒》
在当今数字化时代,软件系统的安全性愈发成为人们关注的焦点。尤其是在 C多进程编程领域,如何确保进程间的安全交互与数据保护,是每一位开发者都必须面对的重要课题。而进程隔离机制,犹如一座坚固的堡垒,为 C多进程编程…...
构建无障碍的数字世界:深入探讨Web可访问性指南
文章目录 前言一、什么是Web可访问性?二、Web内容无障碍指南(WCAG)三、ARIA属性的应用四、实践中的Web可访问性结语 前言 在当今高度互联的世界里,互联网已成为人们日常生活不可或缺的一部分。然而,对于数百万残障人士…...

跨境出海安全:如何防止PayPal账户被风控?
今天咱们聊聊那些让人头疼的事儿——PayPal账户被风控。不少跨境电商商家反馈,我们只是想要安安静静地在网上做个小生意,结果不知道为什么,莫名其妙账户就被冻结了。 但其实每个封禁都是有原因的,今天就来给大家分享分享可能的原…...

学习日记_20241123_聚类方法(MeanShift)
前言 提醒: 文章内容为方便作者自己后日复习与查阅而进行的书写与发布,其中引用内容都会使用链接表明出处(如有侵权问题,请及时联系)。 其中内容多为一次书写,缺少检查与订正,如有问题或其他拓展…...
AI编程和AI绘画哪个更适合创业?
AI编程和AI绘画各有优势,适合创业的方向取决于你的资源、兴趣、市场需求和技术能力。以下是两者的对比分析,帮助你选择更适合的方向: AI编程 优势 1、广泛应用领域: 涉及自动化、数据分析、自然语言处理、计算机视觉等多个领域&a…...

macOS 无法安装第三方app,启用任何来源的方法
升级新版本 MacOS 后,安装下载的软件时,不能在 ”安全性与隐私” 中找不到 ”任何来源” 选项。 1. 允许展示任何来源 点击 启动器 (Launchpad) – 其他 (Other) – 终端 (Terminal): 打开终端后,输入以下代码回车: …...

关于SpringBoot集成Kafka
关于Kafka Apache Kafka 是一个分布式流处理平台,广泛用于构建实时数据管道和流应用。它能够处理大量的数据流,具有高吞吐量、可持久化存储、容错性和扩展性等特性。 Kafka一般用作实时数据流处理、消息队列、事件架构驱动等 Kafka的整体架构 ZooKeeper:…...

4.STM32之通信接口《精讲》之IIC通信---软件实现IIC《深入浅出》面试必备!
接下正式,进入软件编写IIC时序了,并实现对MPU6050的控制,既然是软件实现,那么硬件方面,我仅需两根控制线即可,即:数据控制线SDA,时钟控制线SCL。(人为软件层面定义的&…...
6G通信技术对比5G有哪些不同?
6G,即第六代移动通信技术,是5G之后的延伸,代表了一种全新的通信技术发展方向。与5G相比,6G在多个方面都有显著的不同和提升,以下是对6G通信技术及其与5G差异的详细分析: 一、6G的基本特点 更高的传输速率…...
「Mac玩转仓颉内测版28」基础篇8 - 元组类型详解
本篇将介绍 Cangjie 中的元组类型,包括元组的定义、创建、访问、数据解构以及应用场景,帮助开发者掌握元组类型的使用。 关键词 元组类型定义元组创建元组访问数据解构应用场景 一、元组类型概述 在 Cangjie 中,元组是一种用于存储多种数据…...

WebStorm 2024.3/IntelliJ IDEA 2024.3出现elementUI提示未知 HTML 标记、组件引用爆红等问题处理
WebStorm 2024.3/IntelliJ IDEA 2024.3出现elementUI提示未知 HTML 标记、组件引用爆红等问题处理 1. 标题识别elementUI组件爆红 这个原因是: 在官网说明里,才版本2024.1开始,默认启用的 Vue Language Server,但是在 Vue 2 项目…...

机械设计学习资料
免费送大家学习资源,已整理好,仅供学习 下载网址: https://www.zzhlszk.com/?qZ02-%E6%9C%BA%E6%A2%B0%E8%AE%BE%E8%AE%A1%E8%A7%84%E8%8C%83SOP.zip...

Python 快速入门(上篇)❖ Python 字符串
Python 字符串 字符串格式化输出字符串拼接获取字符串长度字符串切片字符串处理方法 字符串格式化输出 name “xhx” age 30 # 方法1 print("我的名字是%s,今年%s岁了。 " % (name, age)) # 方法2 print(f"我的名字是{name},今年{age}岁了。")字符串拼接…...

Ubuntu中使用多版本的GCC
我的系统中已经安装了GCC11.4,在安装cuda时出现以下错误提示: 意思是当前的GCC版本过高,要在保留GCC11.4的同时安装GCC9并可以切换,可以通过以下步骤实现: 步骤 1: 安装 GCC 9 sudo apt-get update sudo apt-get ins…...

1+X应急响应(网络)文件包含漏洞:
常见网络攻击-文件包含漏洞&命令执行漏洞: 文件包含漏洞简介: 分析漏洞产生的原因: 四个函数: 产生漏洞的原因: 漏洞利用条件: 文件包含: 漏洞分类: 本地文件包含: …...
机器学习实战记录(1)
决策树——划分数据集 def splitDataSet(dataSet, axis, value): retDataSet [] #创建返回的数据集列表for featVec in dataSet: #遍历数据集if featVec[axis] value:reducedFeatVec featVec[:axis] #去掉axis特征reducedFeatVec.extend(featVec[axis1…...
PHP8解析php技术10个新特性
PHP8系列是 PHP编程语言的最新主线版本,带来了许多激动人心的新特性和改进。作为一名PHP开发者,了解这些更新能够帮助你编写更高效、安全和现代的代码。 8的核心技术知识点,包括语言特性、性能优化、安全增强以及开发者工具的改进。 Just-In…...
C++模版特化和偏特化
什么是模版特化 特化的含义:所谓特化,就是将泛型搞得具体化一些,从字面上来解释,就是为已有的模板参数进行一些使其特殊化的指定,使得以前不受任何约束的模板参数,或受到特定的修饰(例如const或…...

Simulink中Model模块的模型保护功能
在开发工作过程中,用户为想要知道供应商的开发能力,想要供应商的模型进行测试。面对如此要求,为了能够尽快拿到定点项目,供应商会选择一小块算法或是模型以黑盒的形式供客户测试。Simulink的Model模块除了具有模块引用的功能之外&…...

深入剖析AI大模型:大模型时代的 Prompt 工程全解析
今天聊的内容,我认为是AI开发里面非常重要的内容。它在AI开发里无处不在,当你对 AI 助手说 "用李白的风格写一首关于人工智能的诗",或者让翻译模型 "将这段合同翻译成商务日语" 时,输入的这句话就是 Prompt。…...
React hook之useRef
React useRef 详解 useRef 是 React 提供的一个 Hook,用于在函数组件中创建可变的引用对象。它在 React 开发中有多种重要用途,下面我将全面详细地介绍它的特性和用法。 基本概念 1. 创建 ref const refContainer useRef(initialValue);initialValu…...

JavaScript 中的 ES|QL:利用 Apache Arrow 工具
作者:来自 Elastic Jeffrey Rengifo 学习如何将 ES|QL 与 JavaScript 的 Apache Arrow 客户端工具一起使用。 想获得 Elastic 认证吗?了解下一期 Elasticsearch Engineer 培训的时间吧! Elasticsearch 拥有众多新功能,助你为自己…...

自然语言处理——Transformer
自然语言处理——Transformer 自注意力机制多头注意力机制Transformer 虽然循环神经网络可以对具有序列特性的数据非常有效,它能挖掘数据中的时序信息以及语义信息,但是它有一个很大的缺陷——很难并行化。 我们可以考虑用CNN来替代RNN,但是…...
Unit 1 深度强化学习简介
Deep RL Course ——Unit 1 Introduction 从理论和实践层面深入学习深度强化学习。学会使用知名的深度强化学习库,例如 Stable Baselines3、RL Baselines3 Zoo、Sample Factory 和 CleanRL。在独特的环境中训练智能体,比如 SnowballFight、Huggy the Do…...

mysql已经安装,但是通过rpm -q 没有找mysql相关的已安装包
文章目录 现象:mysql已经安装,但是通过rpm -q 没有找mysql相关的已安装包遇到 rpm 命令找不到已经安装的 MySQL 包时,可能是因为以下几个原因:1.MySQL 不是通过 RPM 包安装的2.RPM 数据库损坏3.使用了不同的包名或路径4.使用其他包…...
iOS性能调优实战:借助克魔(KeyMob)与常用工具深度洞察App瓶颈
在日常iOS开发过程中,性能问题往往是最令人头疼的一类Bug。尤其是在App上线前的压测阶段或是处理用户反馈的高发期,开发者往往需要面对卡顿、崩溃、能耗异常、日志混乱等一系列问题。这些问题表面上看似偶发,但背后往往隐藏着系统资源调度不当…...

Rust 开发环境搭建
环境搭建 1、开发工具RustRover 或者vs code 2、Cygwin64 安装 https://cygwin.com/install.html 在工具终端执行: rustup toolchain install stable-x86_64-pc-windows-gnu rustup default stable-x86_64-pc-windows-gnu 2、Hello World fn main() { println…...

Ubuntu系统复制(U盘-电脑硬盘)
所需环境 电脑自带硬盘:1块 (1T) U盘1:Ubuntu系统引导盘(用于“U盘2”复制到“电脑自带硬盘”) U盘2:Ubuntu系统盘(1T,用于被复制) !!!建议“电脑…...

ubuntu系统文件误删(/lib/x86_64-linux-gnu/libc.so.6)修复方案 [成功解决]
报错信息:libc.so.6: cannot open shared object file: No such file or directory: #ls, ln, sudo...命令都不能用 error while loading shared libraries: libc.so.6: cannot open shared object file: No such file or directory重启后报错信息&…...