EasilyNET.Mongo.AspNetCore
4.25.905.150
dotnet add package EasilyNET.Mongo.AspNetCore --version 4.25.905.150
NuGet\Install-Package EasilyNET.Mongo.AspNetCore -Version 4.25.905.150
<PackageReference Include="EasilyNET.Mongo.AspNetCore" Version="4.25.905.150" />
<PackageVersion Include="EasilyNET.Mongo.AspNetCore" Version="4.25.905.150" />
<PackageReference Include="EasilyNET.Mongo.AspNetCore" />
paket add EasilyNET.Mongo.AspNetCore --version 4.25.905.150
#r "nuget: EasilyNET.Mongo.AspNetCore, 4.25.905.150"
#:package EasilyNET.Mongo.AspNetCore@4.25.905.150
#addin nuget:?package=EasilyNET.Mongo.AspNetCore&version=4.25.905.150
#tool nuget:?package=EasilyNET.Mongo.AspNetCore&version=4.25.905.150
EasilyNET.Mongo.AspNetCore
一个强大的 MongoDB 驱动服务包,为 ASP.NET Core 应用提供便捷的 MongoDB 数据库操作支持。
核心特性
- 字段命名转换: 数据库中字段名自动驼峰命名,ID/Id 字段自动转换为 ObjectId
- 灵活 ID 配置: 可配置部分类的 Id 字段存储为 string 类型而非 ObjectId,支持子对象和集合成员
- 时间类型本地化: 自动本地化 MongoDB 时间类型
- .NET 6+ 支持: 添加 DateOnly/TimeOnly 类型支持,可序列化为 String 或 long
- 索引管理: 支持通过特性方式自动创建和更新索引
- GridFS 文件存储: 完整的文件存储解决方案,支持大文件分块上传
- S3 兼容 API: 提供与 AWS S3 完全兼容的 REST API 接口
📋 更新日志 (ChangeLogs)
- 自定义格式化: 支持自定义 TimeOnly 和 DateOnly 的格式化格式
- 支持转换为字符串格式存储
- 支持转换为 Ticks (long) 方式存储
- 可自定义实现其他类型转换,如 ulong
- 动态类型支持: 添加 object 和 dynamic 类型支持 (2.20 版本后官方已支持 JsonArray)
- JsonNode 支持: 添加 JsonNode 和 JsonObject 类型支持
添加自定义序列化支持(可选)
JsonNode 类型因为反序列化时不支持 Unicode 字符,如果需要序列化插入至其他地方(例如 Redis),在序列化时需要将 JsonSerializerOptions 的 Encoder 属性设置为 System.Text.Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping.
builder.Services.AddMongoContext<DbContext>(builder.Configuration)
// 添加自定义序列化
builder.Services.RegisterSerializer(new DateOnlySerializerAsString());
builder.Services.RegisterSerializer(new TimeOnlySerializerAsString());
// 或者将他们存储为long类型的Ticks,也可以自己组合使用.
builder.Services.RegisterSerializer(new DateOnlySerializerAsTicks());
builder.Services.RegisterSerializer(new TimeOnlySerializerAsTicks());
// 添加JsonNode支持
builder.Services.RegisterSerializer(new JsonNodeSerializer());
builder.Services.RegisterSerializer(new JsonObjectSerializer());
🚀 快速开始
安装
通过 NuGet 安装 EasilyNET.Mongo.AspNetCore:
dotnet add package EasilyNET.Mongo.AspNetCore
配置连接字符串
在系统环境变量、Docker 容器或 appsettings.json
中设置 MongoDB 连接字符串:
{
"ConnectionStrings": {
"Mongo": "mongodb://localhost:27017/your-database"
}
}
或者使用环境变量:
CONNECTIONSTRINGS_MONGO=mongodb://localhost:27017/your-database
APM 监控支持
支持 APM 探针监控,基于 SkyAPM.Diagnostics.MongoDB。
📖 使用方法
方法 1: 使用默认依赖注入
var builder = WebApplication.CreateBuilder(args);
// 添加 MongoDB 数据库服务
builder.Services.AddMongoContext<DbContext>(builder.Configuration, c =>
{
// 配置数据库名称,覆盖连接字符串中的数据库名称
c.DatabaseName = "your-database";
// 配置不需要将 Id 字段存储为 ObjectId 的类型
// 使用 $unwind 操作符时,ObjectId 在转换上会有问题,所以调整为字符串
c.ObjectIdToStringTypes = new()
{
typeof(YourEntityType)
};
// 是否使用默认转换配置,包含以下内容:
// 1. 小驼峰字段名称,如: pageSize, linkPhone
// 2. 忽略代码中未定义的字段
// 3. 将 ObjectId 字段 _id 映射到实体中的 ID 或 Id 字段,反之亦然
// 4. 将枚举类型存储为字符串,如: Gender.男 存储为 "男" 而非 int 类型
c.DefaultConventionRegistry = true;
// 配置自定义 Convention
c.ConventionRegistry = new()
{
{
$"{SnowId.GenerateNewId()}",
new() { new IgnoreIfDefaultConvention(true) }
}
};
// 通过 ClientSettings 配置特殊功能
c.ClientSettings = cs =>
{
// 对接 SkyAPM 的 MongoDB 探针或其他事件订阅器
cs.ClusterConfigurator = cb => cb.Subscribe(new ActivityEventSubscriber());
};
});
// 添加 .NET 6+ 新 TimeOnly 和 DateOnly 数据类型的序列化方案
builder.Services.RegisterSerializer(new DateOnlySerializerAsString());
builder.Services.RegisterSerializer(new TimeOnlySerializerAsString());
// 注册其他序列化方案
builder.Services.RegisterSerializer(new DoubleSerializer(BsonType.Double));
var app = builder.Build();
方法 2: 使用 EasilyNET.AutoDependencyInjection
安装依赖包:
dotnet add package EasilyNET.AutoDependencyInjection
创建 EasilyNETMongoModule.cs:
public class EasilyNETMongoModule : AppModule
{
/// <summary>
/// 配置和注册服务
/// </summary>
/// <param name="context"></param>
public override void ConfigureServices(ConfigureServicesContext context)
{
var config = context.Services.GetConfiguration();
// 使用 IConfiguration 的方式注册例子,使用链接字符串,仅需将config替换成连接字符即可.
//context.Services.AddMongoContext<DbContext>(config, c =>
//{
// // 配置数据库名称,覆盖掉连接字符串中的数据库名称
// c.DatabaseName = "test23";
// // 配置不需要将Id字段存储为ObjectID的类型.使用$unwind操作符的时候,ObjectId在转换上会有一些问题,所以需要将其调整为字符串.
// c.ObjectIdToStringTypes = new()
// {
// typeof(MongoTest2)
// };
// // 是否使用默认转换配置.包含如下内容:
// // 1.小驼峰字段名称 如: pageSize ,linkPhone
// // 2.忽略代码中未定义的字段
// // 3.将ObjectID字段 _id 映射到实体中的ID或者Id字段,反之亦然.在存入数据的时候将Id或者ID映射为 _id
// // 4.将枚举类型存储为字符串, 如: Gender.男 存储到数据中为 男,而不是 int 类型
// c.DefaultConventionRegistry = true;
// c.ConventionRegistry= new()
// {
// {
// $"{SnowId.GenerateNewId()}",
// new() { new IgnoreIfDefaultConvention(true) }
// }
// };
// // 通过ClientSettings来配置一些使用特殊的东西
// c.ClientSettings = cs =>
// {
// // 对接 SkyAPM 的 MongoDB探针或者别的事件订阅器
// cs.ClusterConfigurator = cb => cb.Subscribe(new ActivityEventSubscriber());
// };
//});
//context.Services.AddMongoContext<DbContext2>(config);
//context.Services.RegisterSerializer(new GuidSerializer(GuidRepresentation.Standard));
// 例子二:使用MongoClientSettings配置
context.Services.AddMongoContext<DbContext>(new MongoClientSettings
{
Servers = new List<MongoServerAddress> { new("127.0.0.1", 27018) },
Credential = MongoCredential.CreateCredential("admin", "guest", "guest"),
// 对接 SkyAPM 的 MongoDB探针
ClusterConfigurator = cb => cb.Subscribe(new DiagnosticsActivityEventSubscriber())
}, c =>
{
// 配置数据库名称,覆盖掉连接字符串中的数据库名称
c.DatabaseName = "test23";
// 配置不需要将Id字段存储为ObjectID的类型.使用$unwind操作符的时候,ObjectId在转换上会有一些问题.
c.ObjectIdToStringTypes = new()
{
typeof(MongoTest2)
};
// 是否使用默认转换配置.包含如下内容:
// 1.小驼峰字段名称 如: pageSize ,linkPhone
// 2.忽略代码中未定义的字段
// 3.将ObjectID字段 _id 映射到实体中的ID或者Id字段,反之亦然.在存入数据的时候将Id或者ID映射为 _id
// 4.将枚举类型存储为字符串, 如: Gender.男 存储到数据中为 男,而不是 int 类型
c.DefaultConventionRegistry = true;
c.ConventionRegistry= new()
{
{
$"{SnowId.GenerateNewId()}",
new() { new IgnoreIfDefaultConvention(true) }
}
};
});
// 注册另一个DbContext
context.Services.AddMongoContext<DbContext2>(config, c =>
{
c.DefaultConventionRegistry = true;
c.ConventionRegistry = new()
{
{
$"{SnowId.GenerateNewId()}",
new() { new IgnoreIfDefaultConvention(true) }
}
};
});
}
}
- 创建 AppWebModule.cs 并添加 EasilyNETMongoModule
/**
* 要实现自动注入,一定要在这个地方添加
*/
[DependsOn(
typeof(DependencyAppModule),
typeof(EasilyNETMongoModule)
)]
public class AppWebModule : AppModule
{
/// <summary>
/// 注册和配置服务
/// </summary>
/// <param name="context"></param>
public override void ConfigureServices(ConfigureServicesContext context)
{
base.ConfigureServices(context);
_ = context.Services.AddHttpContextAccessor();
}
/// <summary>
/// 注册中间件
/// </summary>
/// <param name="context"></param>
public override void ApplicationInitialization(ApplicationContext context)
{
base.ApplicationInitialization(context);
var app = context.GetApplicationBuilder();
_ = app.UseAuthorization();
}
}
- 最后在 Program.cs 中添加如下内容
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
// 自动注入服务模块
builder.Services.AddApplication<AppWebModule>();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment()) _ = app.UseDeveloperExceptionPage();
// 添加自动化注入的一些中间件.
app.InitializeApplication();
app.MapControllers();
app.Run();
📁 GridFS 文件存储
GridFS 是 MongoDB 的分布式文件系统,支持存储超过 16MB 的文件。
基础使用
- 注册服务:
// 需要提前注册 IMongoDatabase,或使用其他重载
builder.Services.AddMongoGridFS();
- 依赖注入使用:
public class FileService(IGridFSBucket bucket)
{
private readonly IGridFSBucket _bucket = bucket;
public async Task UploadFileAsync(Stream stream, string filename)
{
var id = await _bucket.UploadFromStreamAsync(filename, stream);
return id;
}
public async Task<Stream> DownloadFileAsync(string filename)
{
return await _bucket.OpenDownloadStreamByNameAsync(filename);
}
}
### S3 兼容 API
EasilyNET.Mongo.AspNetCore 提供了与 AWS S3 完全兼容的 REST API,使用 GridFS 作为后端存储。
#### 🎯 核心特性
- **100% S3 API 兼容**: 支持所有核心 S3 操作
- **高效性能**: 流式处理,支持大文件上传下载
- **完整功能**: 多部分上传、批量删除、Range 请求等
- **客户端兼容**: 支持 AWS CLI、SDK、MinIO Client 等
#### ✅ 已实现的 S3 API
| 操作 | HTTP 方法 | 端点 | 状态 |
|------|----------|------|------|
| 上传对象 | PUT | `/{bucket}/{key}` | ✅ 完全兼容 |
| 下载对象 | GET | `/{bucket}/{key}` | ✅ 完全兼容,支持 Range |
| 获取元数据 | HEAD | `/{bucket}/{key}` | ✅ 完全兼容 |
| 删除对象 | DELETE | `/{bucket}/{key}` | ✅ 完全兼容 |
| 列出对象 | GET | `/{bucket}` | ✅ 完全兼容 |
| 列出对象 V2 | GET | `/{bucket}/list` | ✅ 完全兼容 |
| 创建存储桶 | PUT | `/{bucket}` | ✅ 完全兼容 |
| 删除存储桶 | DELETE | `/{bucket}` | ✅ 完全兼容 |
| 列出存储桶 | GET | `/~/s3` | ✅ 完全兼容 |
| 检查存储桶 | HEAD | `/{bucket}` | ✅ 完全兼容 |
#### 🚀 高级功能
- **多部分上传**: 支持大文件分块上传
- **批量删除**: 一次删除多个对象
- **Range 请求**: 支持断点续传和部分下载
- **元数据支持**: 完全支持自定义元数据 (x-amz-meta-*)
- **认证中间件**: 基础 AWS Signature V4 支持
- **缓存机制**: 元数据缓存优化性能
- **流式处理**: 内存高效的大文件处理
#### 📋 配置 S3 兼容服务
```csharp
var builder = WebApplication.CreateBuilder(args);
// 注册 MongoDB 上下文
builder.Services.AddMongoContext<DbContext>(builder.Configuration);
// 注册 GridFS 服务
builder.Services.AddMongoGridFS(builder.Configuration);
// 注册 S3 对象存储服务
builder.Services.AddSingleton<IObjectStorage, GridFSObjectStorage>();
// 注册 IAM 策略管理器
builder.Services.AddMongoS3IamPolicyManager();
var app = builder.Build();
// 配置 S3 认证中间件
app.UseS3Authentication(opts =>
{
opts.Enabled = true;
opts.RequireAuthentication = false; // 设置为 true 启用强制认证
});
// 注册 S3 兼容控制器
app.MapControllers();
app.Run();
🧪 测试示例
# 创建存储桶
curl -X PUT http://localhost:5000/s3/test-bucket
# 上传文件
curl -X PUT -T file.txt http://localhost:5000/s3/test-bucket/file.txt
# 下载文件
curl -X GET http://localhost:5000/s3/test-bucket/file.txt -o downloaded.txt
# 列出对象
curl -X GET "http://localhost:5000/s3/test-bucket?list-type=2"
# 删除文件
curl -X DELETE http://localhost:5000/s3/test-bucket/file.txt
🔧 AWS SDK 集成
var s3Client = new AmazonS3Client(
"AKIAIOSFODNN7EXAMPLE", // Access Key ID
"wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY", // Secret Access Key
new AmazonS3Config
{
ServiceURL = "http://localhost:5000/s3",
ForcePathStyle = true
});
// 上传对象
await s3Client.PutObjectAsync(new PutObjectRequest
{
BucketName = "test-bucket",
Key = "test-file.txt",
ContentBody = "Hello, GridFS!"
});
// 下载对象
var response = await s3Client.GetObjectAsync("test-bucket", "test-file.txt");
📊 性能优化
- 流式处理: 避免大文件内存加载
- 智能缓存: 元数据缓存减少数据库查询
- 异步操作: 支持高并发请求
- 连接池: 优化数据库连接使用
🎯 兼容性对比
功能类别 | 兼容度 | 说明 |
---|---|---|
基础操作 | 100% | PUT/GET/DELETE/HEAD 完全兼容 |
列表操作 | 100% | ListObjects 和 ListObjectsV2 |
多部分上传 | 100% | 完整的分块上传流程 |
批量操作 | 100% | DeleteObjects 完全支持 |
元数据 | 100% | 自定义元数据完全支持 |
Range 请求 | 100% | 断点续传和部分下载 |
存储桶操作 | 100% | 创建/删除/列表完全支持 |
认证 | 80% | 基础 AWS Signature V4 支持 |
服务器端加密 | 90% | 支持 AES256 加密 |
对象版本 | 70% | 基础版本管理支持 |
🏷️ 索引管理
EasilyNET.Mongo.AspNetCore 支持基于特性自动为实体类创建 MongoDB 索引,会根据字段命名约定(如小驼峰)自动适配索引字段名。
核心特性
- 单字段索引: 使用
[MongoIndex]
特性声明 - 复合索引: 使用
[MongoCompoundIndex]
特性声明 - 索引类型: 支持唯一索引、文本索引、地理空间索引等
- 自动适配: 字段名自动适配命名约定
使用示例
public class User
{
[MongoIndex(EIndexType.Ascending, Unique = true)]
public string UserName { get; set; } = string.Empty;
[MongoIndex(EIndexType.Descending)]
public DateTime CreatedAt { get; set; }
}
[MongoCompoundIndex(
new[] { "UserName", "CreatedAt" },
new[] { EIndexType.Ascending, EIndexType.Descending },
Unique = true)]
public class Log
{
public string UserName { get; set; } = string.Empty;
public DateTime CreatedAt { get; set; }
}
配置索引创建
var app = builder.Build();
// 自动为所有集合创建索引,字段名自动适配命名约定
app.UseCreateMongoIndexes<DbContext>();
// 若存在多个 DbContext,需要多次应用
app.UseCreateMongoIndexes<DbContext2>();
注意事项
- 自动索引创建会比对现有索引定义
- 若定义不一致会自动删除并重建(通过名称匹配)
- 若不存在对应名称,不会删除原有索引(避免手动创建的索引失效)
📚 更多资源
最后更新: 2025 年 9 月 3 日
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 is compatible. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- EasilyNET.Core (>= 4.25.905.150)
- EasilyNET.Mongo.Core (>= 4.25.905.150)
-
net8.0
- EasilyNET.Core (>= 4.25.905.150)
- EasilyNET.Mongo.Core (>= 4.25.905.150)
-
net9.0
- EasilyNET.Core (>= 4.25.905.150)
- EasilyNET.Mongo.Core (>= 4.25.905.150)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
Version | Downloads | Last Updated | |
---|---|---|---|
4.25.905.150 | 111 | 9/5/2025 | |
4.25.820.100 | 131 | 8/20/2025 | |
4.25.814.175 | 132 | 8/14/2025 | |
4.25.731.155 | 102 | 7/31/2025 | |
4.25.724.1 | 493 | 7/23/2025 | |
4.25.720.80 | 252 | 7/20/2025 | |
4.25.716.42 | 143 | 7/15/2025 | |
4.25.617.153 | 157 | 6/17/2025 | |
4.25.616.190 | 146 | 6/16/2025 | |
4.25.616.182 | 147 | 6/16/2025 | |
4.25.613.111 | 283 | 6/13/2025 | |
4.25.609.190 | 828 | 6/9/2025 | |
3.24.929.131 | 302 | 9/29/2024 | |
3.24.929.122 | 289 | 9/29/2024 | |
3.24.926.184 | 299 | 9/26/2024 | |
3.24.926.182 | 295 | 9/26/2024 | |
3.24.926.175 | 292 | 9/26/2024 | |
3.24.924.160 | 297 | 9/24/2024 | |
3.24.924.133 | 297 | 9/24/2024 | |
3.24.924.124 | 288 | 9/24/2024 | |
3.24.924.10 | 294 | 9/23/2024 | |
3.24.924.1 | 292 | 9/23/2024 | |
3.24.923.234 | 286 | 9/23/2024 | |
3.24.923.232 | 292 | 9/23/2024 | |
3.24.923.155 | 294 | 9/23/2024 | |
3.24.919.92 | 293 | 9/19/2024 | |
3.24.914.125 | 457 | 9/14/2024 | |
3.24.914.115 | 318 | 9/14/2024 | |
3.24.914.111 | 291 | 9/14/2024 | |
3.24.911.95 | 288 | 9/11/2024 | |
3.24.908.215 | 283 | 9/8/2024 | |
3.24.904.200 | 440 | 9/4/2024 | |
3.24.828.163 | 293 | 8/28/2024 | |
3.24.820.173 | 296 | 8/20/2024 | |
3.24.814.92 | 308 | 8/14/2024 | |
3.24.812.115 | 297 | 8/12/2024 | |
3.24.802.100 | 275 | 8/2/2024 | |
3.24.801.162 | 287 | 8/1/2024 | |
3.24.801.160 | 286 | 8/1/2024 | |
3.24.801.155 | 286 | 8/1/2024 | |
3.24.730.164 | 276 | 7/30/2024 | |
3.24.730.91 | 277 | 7/30/2024 | |
3.24.724.91 | 279 | 7/24/2024 | |
3.24.718.105 | 291 | 7/18/2024 | |
3.24.716.95 | 288 | 7/16/2024 | |
3.24.712.94 | 286 | 7/12/2024 | |
3.24.710.14 | 285 | 7/9/2024 | |
3.24.709.105 | 288 | 7/9/2024 | |
3.24.704.94 | 293 | 7/4/2024 | |
3.24.701.90 | 293 | 7/1/2024 | |
3.24.628.114 | 296 | 6/28/2024 | |
3.24.627.145 | 287 | 6/27/2024 | |
3.24.620.160 | 297 | 6/20/2024 | |
3.24.613.115 | 295 | 6/13/2024 | |
3.24.612.95 | 287 | 6/12/2024 | |
3.24.528.90 | 290 | 5/28/2024 | |
3.24.522.84 | 299 | 5/22/2024 | |
3.24.512.213 | 295 | 5/12/2024 | |
3.24.508.112 | 315 | 5/8/2024 | |
2.2024.428.71 | 290 | 4/28/2024 | |
2.2024.427.1128 | 291 | 4/27/2024 | |
2.2.72 | 367 | 4/14/2024 | |
2.2.71 | 300 | 4/12/2024 | |
2.2.8 | 287 | 4/26/2024 | |
2.2.6 | 299 | 4/10/2024 | |
2.2.5 | 307 | 3/26/2024 | |
2.2.4 | 309 | 3/25/2024 | |
2.2.3 | 305 | 3/24/2024 | |
2.2.2 | 306 | 3/21/2024 | |
2.2.1 | 307 | 3/20/2024 | |
2.2.0 | 305 | 3/13/2024 | |
2.1.9 | 310 | 2/21/2024 | |
2.1.8 | 300 | 2/18/2024 | |
2.1.7 | 306 | 2/16/2024 | |
2.1.6 | 324 | 2/14/2024 | |
2.1.5 | 303 | 2/14/2024 | |
1.9.1 | 340 | 11/1/2023 | |
1.9.0 | 336 | 10/19/2023 | |
1.9.0-preview2 | 526 | 10/12/2023 | |
1.9.0-preview1 | 296 | 10/12/2023 | |
1.8.9 | 374 | 10/11/2023 | |
1.8.8 | 347 | 10/11/2023 | |
1.8.7-rc2 | 316 | 9/21/2023 | |
1.8.7-rc1 | 305 | 9/12/2023 | |
1.8.6 | 359 | 8/31/2023 | |
1.8.5 | 1,043 | 8/25/2023 | |
1.8.4 | 357 | 8/24/2023 | |
1.8.3 | 362 | 8/23/2023 | |
1.8.2 | 437 | 8/22/2023 | |
1.8.1 | 379 | 8/18/2023 | |
1.8.0 | 359 | 8/15/2023 | |
1.7.9 | 398 | 8/11/2023 | |
1.7.8 | 342 | 8/11/2023 | |
1.7.7 | 387 | 8/10/2023 | |
1.7.6 | 377 | 8/9/2023 | |
1.7.5 | 434 | 8/9/2023 | |
1.7.4 | 466 | 8/3/2023 | |
1.7.3 | 379 | 8/1/2023 | |
1.7.2 | 368 | 7/31/2023 | |
1.7.1 | 369 | 7/27/2023 | |
1.7.0 | 380 | 7/25/2023 | |
1.6.9 | 369 | 7/25/2023 | |
1.6.8 | 364 | 7/24/2023 | |
1.6.7 | 388 | 7/20/2023 | |
1.6.6 | 392 | 7/19/2023 | |
1.6.5 | 354 | 7/19/2023 | |
1.6.4 | 369 | 7/17/2023 | |
1.6.3 | 345 | 7/17/2023 | |
1.6.2 | 409 | 7/12/2023 | |
1.6.1 | 404 | 6/30/2023 | |
1.6.0 | 340 | 6/30/2023 |