本文主要是使用异步方式,体验
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
左右;