RuoVea.OmiApi.Config
10.0.0.7
dotnet add package RuoVea.OmiApi.Config --version 10.0.0.7
NuGet\Install-Package RuoVea.OmiApi.Config -Version 10.0.0.7
<PackageReference Include="RuoVea.OmiApi.Config" Version="10.0.0.7" />
<PackageVersion Include="RuoVea.OmiApi.Config" Version="10.0.0.7" />
<PackageReference Include="RuoVea.OmiApi.Config" />
paket add RuoVea.OmiApi.Config --version 10.0.0.7
#r "nuget: RuoVea.OmiApi.Config, 10.0.0.7"
#:package RuoVea.OmiApi.Config@10.0.0.7
#addin nuget:?package=RuoVea.OmiApi.Config&version=10.0.0.7
#tool nuget:?package=RuoVea.OmiApi.Config&version=10.0.0.7
RuoVea.OmiApi.Config
系统配置管理 —— 高性能、可缓存的参数配置 API NuGet 包。
目录
概览
RuoVea.OmiApi.Config 是一个即装即用的 NuGet 包,为 .NET 应用提供系统级参数配置的完整管理能力。它封装了从数据库自动建表、种子数据填充、RESTful API 暴露到缓存加速的全流程,开发者仅需一行注册即可获得生产级的配置中心。
核心特性一览
| 特性 | 说明 |
|---|---|
| 参数配置 CRUD | 分页查询、单条查询、添加、修改、删除、批量删除 |
| 缓存优先读取 | Cache-Aside 模式,缓存键前缀 sys_config:,命中即返回 |
| 大小写不敏感 | 配置编码查询自动转小写,避免大小写不一致导致查不到 |
| 批量缓存读写 | GetConfigCaches / GetConfigs 支持批量操作,减少 IO |
| 8 条内置种子数据 | 演示环境、验证码、默认密码、注册/找回密码、水印、操作日志 |
| CodeFirst 自动建表 | AddConfigInitSetup 一键完成建表与种子数据插入 |
| 系统参数保护 | SysFlag=Y 的配置不可删除,防止误操作 |
| 多租户支持 | 实体实现 ITenantEntity,原生支持多租户隔离 |
| 国际化错误消息 | 基于 .resx 资源文件,支持多语言错误提示 |
| 生命周期可配 | 支持 Scoped / Singleton / Transient 三种 ServiceLifetime |
| 分组列表查询 | 按 GroupCode 去重返回分组编码列表 |
| 泛型类型转换 | GetConfigValueCache<T> 将配置值自动转为目标类型 |
架构概览
+-----------------------------------------------------------+
| Swagger UI |
| GroupName = "system" |
+-----------+-----------+-----------+-----------+-----------+
| | | |
GET /api/SysConfig/GetPagesAsync 分页查询
GET /api/SysConfig/GetDataAsync 单条查询
POST /api/SysConfig/AddDataAsync 添加
PUT /api/SysConfig/UpdateDataAsync 修改
DELETE /api/SysConfig/DeleteDataAsync 删除
POST /api/SysConfig/BatchDelete 批量删除
GET /api/SysConfig/GetConfigCache 缓存读取
GET /api/SysConfig/GetConfigCaches 批量缓存读取
GET /api/SysConfig/GetConfig 数据库直读
GET /api/SysConfig/GetConfigs 批量数据库直读
GET /api/SysConfig/GetDemoEnvFlag 演示环境开关 [AllowAnonymous]
GET /api/SysConfig/GetGroupList 分组列表
| | | |
+-----------+-----------+-----------+-----------+-----------+
| SysConfigService |
| (IApplicationService via DynamicWebApi) |
+-----------+------------------------------+---------------+
| |
+-----------v-----------+ +----------v-----------+
| CacheFactery.Cache | | SugarRepository |
| (Redis / Memory) | | <SysConfig> |
| Key: sys_config:{code} | | (SqlSugar ORM) |
+-----------------------+ +----------+-----------+
|
+------------v-----------+
| SysConfig 表 |
| MySql/SqlServer/ |
| SQLite/Pg/Oracle ... |
+------------------------+
数据模型
SysConfig (参数配置表) ──继承──> EntityBase (基础字段)
│ ├── Id, CreateTime, UpdateTime
│ ├── IsDelete (软删除)
│ └── CreateUserId, UpdateUserId, ...
│
└──实现──> ITenantEntity
└── TenantId (多租户隔离)
| 字段 | 类型 | 说明 |
|---|---|---|
Id |
long |
主键 |
TenantId |
long? |
租户 Id |
Name |
string |
配置名称 |
Code |
string |
配置编码(唯一,大小写不敏感) |
Value |
string |
配置值 |
SysFlag |
YesOrNot? |
是否系统参数(Y=是,不可删除;N=否) |
Remark |
string |
备注 |
IsDisable |
YesOrNot? |
是否禁用 |
GroupCode |
string |
分组编码 |
Sort |
int? |
排序(默认 100) |
安装
.NET 8.0
dotnet add package RuoVea.OmiApi.Config --version 8.0.0.22
Install-Package RuoVea.OmiApi.Config -Version 8.0.0.22
.NET 10.0
dotnet add package RuoVea.OmiApi.Config --version 10.0.0.4
Install-Package RuoVea.OmiApi.Config -Version 10.0.0.4
依赖项:RuoVea.DynamicWebApi, RuoVea.ExSugar, RuoVea.ExConfig, RuoVea.ExUtil, RuoVea.ExDto, RuoVea.ExEnum, RuoVea.ExCache, SqlSugar, Mapster
30 秒快速开始
1. 数据库配置(appsettings.json)
{
"ConnectionConfigs": [
{
"DbType": "Sqlite",
"ConnectionString": "DataSource=./ruovea.db"
}
],
"DbInitConfig": {
"InitTable": true,
"InitSeedData": true
},
"Swagger": {
"ApiVersions": [
{
"Title": "系统应用",
"Version": "system"
}
]
}
}
2. Program.cs 注册
// <summary>
// 注册 DynamicWebApi 动态 API 组件(生产环境添加 /openapi/api 前缀)
// </summary>
if (builder.Environment.IsProduction())
{
builder.Services.AddDynamicWebApi(options =>
{
options.DefaultApiPrefix = "/openapi/api";
options.RemoveControllerPostfixes = new List<string> { "AppService", "Service" };
options.RemovePrefix = new List<string> { "get", "post" };
});
}
else
{
builder.Services.AddDynamicWebApi(options =>
{
options.RemoveControllerPostfixes = new List<string> { "AppService", "Service" };
options.RemovePrefix = new List<string> { "get", "post" };
});
}
// <summary>
// 注册 ORM(SqlSugar),需配合 RuoVea.ExSugar 或自行注册 ISqlSugarClient
// </summary>
builder.Services.AddSqlSugarSetup();
// <summary>
// 注册系统配置服务,默认 Scoped 生命周期
// </summary>
builder.Services.AddOmiConfigSetup();
// <summary>
// 初始化数据库表结构与种子数据(异步后台执行)
// </summary>
builder.Services.AddConfigInitSetup();
3. 启动并访问 Swagger
启动项目后,访问 Swagger UI(默认 /swagger),在下拉列表中选择 "系统应用" 分组即可看到所有配置管理 API。
核心场景
场景一:参数配置 CRUD 管理
完整的增删改查 + 批量删除 + 分页查询能力,所有接口自动暴露为 RESTful API。
+--------+ +-------------------+ +-------------+
| Client | ----> | SysConfigService | ----> | 数据库 |
+--------+ REST +-------------------+ ORM +-------------+
| AddDataAsync | | INSERT |
| UpdateDataAsync | | UPDATE |
| DeleteDataAsync | | SOFT DELETE |
| BatchDelete | | BULK DELETE |
| GetPagesAsync | | SELECT PAGE |
| GetDataAsync | | SELECT ONE |
+-------------------+ +-------------+
// <summary>
// 分页查询参数配置
// </summary>
public async Task<PageResult<SysConfigDto>> QueryConfigsAsync()
{
var param = new SysConfigParam
{
PageNo = 1,
PageSize = 20,
GroupCode = "Default"
};
// 异步方式
return await _sysConfigService.GetPagesAsync(param);
// 同步方式
// return _sysConfigService.GetPagesAsync(param).GetAwaiter().GetResult();
}
// <summary>
// 添加一条配置记录
// </summary>
public async Task<bool> AddConfigAsync()
{
var input = new SysConfigInputDto
{
Name = "日志保留天数",
Code = "log_retention_days",
Value = "30",
SysFlag = YesOrNot.N,
GroupCode = "Log",
Sort = 10
};
// 异步方式
return await _sysConfigService.AddDataAsync(input);
// 同步方式
// return _sysConfigService.AddDataAsync(input).GetAwaiter().GetResult();
}
// <summary>
// 批量删除配置(自动过滤系统参数)
// </summary>
public async Task BatchDeleteConfigsAsync(List<long> ids)
{
// ⚠️ 系统参数 (SysFlag=Y) 会被自动排除,不会被删除
await _sysConfigService.BatchDelete(ids);
}
场景二:缓存优先的配置读取(Cache-Aside)
高并发场景下推荐使用带缓存的读取方法,避免频繁访问数据库。内置 Cache-Aside 模式:缓存命中直接返回,未命中则查库并回填缓存。
+--------+ +-------------------+ +-------------+ +-------------+
| Client | --> | GetConfigCache() | --> | 缓存层 | --> | 数据库 |
+--------+ +-------------------+ +-------------+ +-------------+
| | 命中? ^
| +---YES---> 返回 |
| | |
| +---NO----> 查库 ------+
| 回填缓存
| |
+<---- 返回 value -------------------+
// <summary>
// 从缓存读取单个配置值
// </summary>
public async Task<string> ReadConfigWithCacheAsync()
{
// 异步方式
var demoFlag = await _sysConfigService.GetConfigCache("dilon_demo_env_flag");
return demoFlag;
// 同步方式
// var demoFlag = _sysConfigService.GetConfigCache("dilon_demo_env_flag").GetAwaiter().GetResult();
// return demoFlag;
}
// <summary>
// 批量从缓存读取多个配置(减少 IO 次数)
// </summary>
public async Task<Dictionary<string, string>> ReadConfigsWithCacheBatchAsync()
{
var codes = new[] { "dilon_demo_env_flag", "dilon_captcha_open", "sys_oplog" };
// 异步方式
var dict = await _sysConfigService.GetConfigCaches(codes);
// 返回: { "dilon_demo_env_flag": "false", "dilon_captcha_open": "false", ... }
return dict;
// 同步方式
// return _sysConfigService.GetConfigCaches(codes).GetAwaiter().GetResult();
}
// <summary>
// 泛型类型转换:直接从缓存获取并转为目标类型
// </summary>
public async Task<bool> ReadConfigAsBoolAsync()
{
// 异步方式
var isDemoEnv = await _sysConfigService.GetConfigValueCache<bool>("dilon_demo_env_flag");
return isDemoEnv;
// 同步方式
// return _sysConfigService.GetConfigValueCache<bool>("dilon_demo_env_flag").GetAwaiter().GetResult();
}
// <summary>
// ⚠️ 缓存一致性:修改/删除配置时会自动失效对应缓存键
// </summary>
public async Task UpdateConfigWithCacheInvalidationAsync()
{
var input = new SysConfigInputDto
{
Id = 142307070902374,
Code = "dilon_demo_env_flag",
Value = "true"
};
// UpdateDataAsync 内部会自动执行:
// 1. 更新数据库
// 2. await CacheFactery.Cache.WriteAsync("sys_config:dilon_demo_env_flag", "true")
await _sysConfigService.UpdateDataAsync(input);
}
场景三:系统参数保护与租户隔离
内置的"系统参数不可删除"保护机制,配合多租户隔离,确保 SAAS 场景下各租户的配置数据互不影响。
+--------+ DELETE /api/SysConfig/DeleteDataAsync?id=123
| Client | ------------------------------------------------>
+--------+ |
v
+-----------------------------+
| DeleteDataAsync() |
+-----------------------------+
|
+--------------v--------------+
| 1. 查询 config 是否存在 |
| └── 不存在? 抛出 D1002 |
| |
| 2. 检查 SysFlag == Y? |
| └── 是? 抛出 D9001 |
| ("禁止删除系统参数") |
| |
| 3. 执行软删除 |
| 4. 删除对应缓存键 |
+----------------------------+
// <summary>
// 尝试删除系统参数 —— 会被拒绝
// </summary>
public async Task AttemptDeleteSysConfigAsync()
{
// 假设 ID 142307070902374 是 SysFlag=Y 的系统参数
var data = new EntityBaseIdDto { Id = 142307070902374 };
try
{
await _sysConfigService.DeleteDataAsync(data);
}
catch (ArgumentException ex)
{
// 捕获: "禁止删除系统参数" (D9001)
Console.WriteLine($"删除被阻止: {ex.Message}");
}
}
// <summary>
// 安全删除:先判断 SysFlag 再决定
// </summary>
public async Task SafeDeleteConfigAsync(long id)
{
// 同步方式获取配置详情
var dto = _sysConfigService.GetDataAsync(new EntityBaseIdDto { Id = id })
.GetAwaiter().GetResult();
if (dto.SysFlag == YesOrNot.Y)
{
Console.WriteLine($"配置 [{dto.Name}] 为系统参数,不可删除");
return;
}
await _sysConfigService.DeleteDataAsync(new EntityBaseIdDto { Id = id });
}
场景四:分组列表查询
按 GroupCode 去重获取所有分组编码列表,适用于前端下拉选择或配置分类导航。
// <summary>
// 查询所有分组编码(去重)
// </summary>
public async Task<List<string>> GetAllGroupsAsync()
{
// 异步方式:不传 groupCode 时返回所有去重后的 GroupCode
var allGroups = await _sysConfigService.GetGroupList(null);
return allGroups;
// 同步方式
// return _sysConfigService.GetGroupList(null).GetAwaiter().GetResult();
}
// <summary>
// 查询指定分组下的配置列表
// </summary>
public async Task<List<string>> GetSpecificGroupsAsync()
{
// 异步方式:传入具体分组编码进行精确匹配
var groups = await _sysConfigService.GetGroupList("Default");
return groups;
// 同步方式
// return _sysConfigService.GetGroupList("Default").GetAwaiter().GetResult();
}
场景五:内置辅助方法调用
SysConfigService 内部提供了多个 [NonAction] 辅助方法,供业务模块直接注入调用:
// <summary>
// 注入 SysConfigService 后直接调用内置辅助方法
// </summary>
public class MyBusinessService
{
private readonly SysConfigService _configService;
/// <summary>
/// 通过 DI 注入 SysConfigService
/// </summary>
public MyBusinessService(SysConfigService configService)
{
_configService = configService;
}
/// <summary>
/// Demo:在业务逻辑中使用配置辅助方法
/// </summary>
public async Task DemoBusinessWithConfigAsync()
{
// <summary>检查演示环境开关</summary>
bool isDemo = await _configService.GetDemoEnvFlag();
// <summary>检查验证码开关</summary>
bool captchaOpen = await _configService.GetCaptchaOpenFlag();
// <summary>获取系统默认密码</summary>
string defaultPwd = await _configService.GetDefault_Password();
// <summary>是否开放注册</summary>
bool enableRegister = await _configService.GetEnableRegister();
// <summary>是否开放找回密码</summary>
bool enableForgotPwd = await _configService.GetEnableForgotPassword();
// <summary>是否记录操作日志</summary>
bool sysOplog = await _configService.GetSysOplog();
// <summary>更新配置值(内部会失效缓存)</summary>
await _configService.UpdateConfigValue("sys_oplog", "false");
}
}
配置选项详解
DbInitConfig 数据库初始化配置
| 配置项 | 类型 | 默认值 | 说明 |
|---|---|---|---|
InitTable |
bool |
false |
是否自动创建 SysConfig 表(CodeFirst) |
InitSeedData |
bool |
false |
是否自动插入种子数据(仅在表不存在时) |
Swagger API 版本分组
| 配置项 | 类型 | 说明 |
|---|---|---|
Title |
string |
API 版本显示标题,用于 Swagger UI 中展示 |
Version |
string |
API 版本标识,此处固定为 "system" |
DI 注册参数
| 重载 | 参数 | 默认值 | 说明 |
|---|---|---|---|
AddOmiConfigSetup() |
serviceLifetime |
Scoped |
从 AppSettings.Configuration 读取配置 |
AddOmiConfigSetup(IConfiguration config) |
config + serviceLifetime |
Scoped |
使用指定 IConfiguration |
AddOmiConfigSetup(Action<DbInitConfig> config) |
config 委托 + serviceLifetime |
Scoped |
使用 Action 委托配置 |
AddConfigInitSetup() |
无 | -- | 初始化表结构与种子数据 |
ServiceLifetime 可选值
| 值 | 适用场景 |
|---|---|
ServiceLifetime.Scoped |
推荐:每次请求一个实例,适合常规 Web API |
ServiceLifetime.Singleton |
⚠️ 慎用:全局单例,需确保线程安全 |
ServiceLifetime.Transient |
每次注入都创建新实例 |
缓存键规范
| 缓存键前缀 | 完整示例 | 说明 |
|---|---|---|
sys_config: |
sys_config:dilon_demo_env_flag |
统一前缀,code 自动转小写 |
CacheConst.KeyConfig |
-- | 常量定义,等于 sys_config: |
API 接口速览
所有接口归属 Swagger 分组 system,基路径由 AddDynamicWebApi 配置决定。
| HTTP 方法 | 完整路径 (示例) | 方法签名 | 说明 |
|---|---|---|---|
GET |
/api/SysConfig/GetPagesAsync |
GetPagesAsync(SysConfigParam data) |
分页查询所有配置 |
GET |
/api/SysConfig/GetDataAsync |
GetDataAsync(EntityBaseIdDto data) |
根据主键查询单条 |
POST |
/api/SysConfig/AddDataAsync |
AddDataAsync(SysConfigInputDto data) |
添加配置 |
PUT |
/api/SysConfig/UpdateDataAsync |
UpdateDataAsync(SysConfigInputDto data) |
修改配置(同步更新缓存) |
DELETE |
/api/SysConfig/DeleteDataAsync |
DeleteDataAsync(EntityBaseIdDto data) |
删除配置(禁止删除系统参数) |
POST |
/api/SysConfig/BatchDelete |
BatchDelete(List<long> ids) |
批量删除(自动排除系统参数) |
GET |
/api/SysConfig/GetConfigCache |
GetConfigCache(string code) |
从缓存读取配置值 |
GET |
/api/SysConfig/GetConfigCaches |
GetConfigCaches(string[] codes) |
批量从缓存读取配置 |
GET |
/api/SysConfig/GetConfig |
GetConfig(string code) |
直接从数据库读取配置 |
GET |
/api/SysConfig/GetConfigs |
GetConfigs(string[] codes) |
批量从数据库读取配置 |
GET |
/api/SysConfig/GetDemoEnvFlag |
GetDemoEnvFlag() |
获取演示环境开关(AllowAnonymous) |
GET |
/api/SysConfig/GetGroupList |
GetGroupList(string groupCode) |
获取分组列表 |
内置种子数据一览
| ID | Name | Code | Value | SysFlag | Sort | GroupCode |
|---|---|---|---|---|---|---|
| 142307070902374 | 演示环境 | dilon_demo_env_flag |
false |
Y | 10 | Default |
| 142307070902365 | 开启验证码 | dilon_captcha_open |
false |
Y | 20 | Default |
| 142307070902343 | 默认密码 | dilon_default_password |
123456 |
Y | 30 | Default |
| 142307070905563 | 开放注册页面 | enable_register |
true |
Y | 40 | Default |
| 142307070905564 | 开放找回密码页面 | enable_forgot_password |
true |
Y | 50 | Default |
| 142307070905565 | 开启水印 | sys_watermark |
true |
Y | 60 | Default |
| 142307070905566 | 水印内容 | sys_web_watermark |
RuoVea.Web |
Y | 70 | Default |
| 1300000000141 | 记录操作日志 | sys_oplog |
true |
Y | 80 | Default |
错误处理与日志
错误码
| 错误码 | 消息 | 触发条件 |
|---|---|---|
D9000 |
名称或编码已存在 | 添加/修改时 Name 重复或 Code 重复(大小写不敏感唯一性校验) |
D1002 |
数据不存在 | 查询、删除目标记录不存在 |
D9001 |
禁止删除系统参数 | 尝试删除 SysFlag=Y 的配置记录 |
异常处理示例
// <summary>
// 捕获并处理配置操作的业务异常
// </summary>
public async Task<string> HandleConfigErrorsAsync()
{
try
{
var input = new SysConfigInputDto
{
Name = "演示环境",
Code = "dilon_demo_env_flag", // D9000: 编码已存在
Value = "false"
};
return await _sysConfigService.AddDataAsync(input) ? "添加成功" : "添加失败";
}
catch (ArgumentException ex)
{
// <summary>业务异常:唯一性冲突 (D9000)、数据不存在 (D1002)、系统参数保护 (D9001)</summary>
Console.WriteLine($"操作被拒绝: {ex.Message}");
return ex.Message;
}
catch (Exception ex)
{
// <summary>未预期的系统异常</summary>
Console.WriteLine($"系统异常: {ex.Message}");
throw;
}
}
// <summary>
// 安全添加:预先检查是否存在同名或同编码配置(同步方式)
// </summary>
public bool SafeAddConfig(SysConfigInputDto input)
{
// 同步方式:先查询再决定
var existing = _sysConfigService.GetPagesAsync(new SysConfigParam
{
Name = input.Name,
Code = input.Code,
PageNo = 1,
PageSize = 1
}).GetAwaiter().GetResult();
if (existing.TotalCount > 0)
{
Console.WriteLine($"配置 [{input.Name}] 已存在,跳过添加");
return false;
}
return _sysConfigService.AddDataAsync(input).GetAwaiter().GetResult();
}
版本迁移指南
v8.0.x 升级至 v10.0.x
| 项目 | v8.0.x | v10.0.x |
|---|---|---|
| Target Framework | net8.0 |
net10.0 |
| NuGet 版本 | 8.0.0.22 |
10.0.0.4 |
| 依赖库版本 | RuoVea.DynamicWebApi 8.0.* |
RuoVea.DynamicWebApi 10.0.* |
| 依赖库版本 | RuoVea.ExSugar 8.0.* |
RuoVea.ExSugar 10.0.* |
迁移步骤:更新目标框架至
net10.0,将 NuGet 包引用版本改为10.0.0.4,API 接口签名与行为完全向后兼容,无需修改业务代码。
常见问题
Q: 为什么调用 GetConfigCache 返回空字符串?
A: 可能原因:配置编码不存在于数据库,或编码拼写不一致。该包使用大小写不敏感的编码查询(内部统一转小写),但仍需确保编码完全匹配种子数据或手动添加的配置记录。
Q: ⚠️ AddConfigInitSetup 使用 Task.Run 异步初始化,是否会阻塞服务启动?
A: AddConfigInitSetup 内部通过 Task.Run 在后台线程执行建表和种子数据插入,不会阻塞 WebApplication.Run()。但在极端情况下(如表结构初始化耗时过长),首次请求到达时表可能尚未就绪。建议在应用部署后确认初始化完成。
Q: ❗ 使用 Singleton 生命周期注册会有什么风险?
A: SysConfigService 内部依赖 SugarRepository<SysConfig>,该仓储通常是 Scoped 生命周期。将服务注册为 Singleton 会捕获作用域内的依赖,可能导致 DbContext 生命周期错乱或内存泄漏。强烈建议保持默认的 Scoped 注册。
Q: 修改或删除配置后缓存会自动更新吗?
A: 自动更新。UpdateDataAsync 会在更新数据库后立即写入缓存;DeleteDataAsync 会在软删除后立即删除对应缓存键。缓存键格式为 sys_config:{code_lower}。无需手动管理缓存。
Q: ⚠️ GetConfig 和 GetConfigCache 有什么区别?
A:
GetConfig:直接查询数据库,每次调用都访问数据库。适合低频访问或需要强一致性的场景。GetConfigCache:Cache-Aside 模式,优先从缓存读取,缓存未命中时查库并回填。适合高并发、高频访问场景,可显著降低数据库压力。
Q: 如何添加自定义种子数据?
A: 在 appsettings.json 中设置 DbInitConfig.InitSeedData=true,然后引用 RuoVea.OmiApi.Config.SeedData 命名空间,继承 SeedDataEntity<SysConfig> 实现自定义 HasData() 方法即可。首次启动时包会自动发现并插入。
Q: 支持哪些数据库?
A: 通过 SqlSugar 支持的数据库均可用,包括:MySql, SqlServer, PostgreSQL, SQLite, Oracle, Dm, Kdbndp, OpenGauss, ClickHouse, GBase, QuestDB, Access, Odbc 等。在 ConnectionConfigs[].DbType 中配置即可。
Q: ❗ 批量删除 (BatchDelete) 会删除系统参数吗?
A: 不会。BatchDelete 内部通过 u.SysFlag != YesOrNot.Y 条件自动过滤系统参数,传入的 ID 列表中即使包含 SysFlag=Y 的记录也不会被删除。
Q: 如何确保配置编码不重复?
A: 添加和修改接口均内置了大小写不敏感的唯一性校验(Code.ToLower() 比较)。如果尝试添加已存在的名称或编码,将抛出 D9000 错误。建议在业务代码中捕获该异常并给出友好提示。
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | 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
- RuoVea.DynamicWebApi (>= 10.0.0)
- RuoVea.ExSugar (>= 10.0.0.9)
NuGet packages (7)
Showing the top 5 NuGet packages that depend on RuoVea.OmiApi.Config:
| Package | Downloads |
|---|---|
|
RuoVea.OmiApi.UserRoleMenu
用户角色菜单管理 |
|
|
RuoVea.OmiApi.SystemApp
系统应用管理 |
|
|
RuoVea.OmiConfig
参数配置 |
|
|
RuoVea.OmiApi.UserRole
用户角色管理 |
|
|
RuoVea.OmiApi.User
用户管理 |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 10.0.0.7 | 25 | 7/21/2026 |
| 10.0.0.6 | 80 | 7/17/2026 |
| 10.0.0.5 | 131 | 7/15/2026 |
| 10.0.0.4 | 291 | 6/24/2026 |
| 10.0.0.3 | 101 | 6/5/2026 |
| 10.0.0.2 | 240 | 5/28/2026 |
| 9.0.0.3 | 249 | 5/28/2026 |
| 9.0.0.2 | 105 | 5/28/2026 |
| 9.0.0.1 | 329 | 3/23/2026 |
| 8.0.0.25 | 32 | 7/21/2026 |
| 8.0.0.24 | 99 | 7/17/2026 |
| 8.0.0.23 | 186 | 7/15/2026 |
| 8.0.0.22 | 504 | 6/24/2026 |
| 8.0.0.21 | 108 | 6/5/2026 |
| 8.0.0.20 | 331 | 5/28/2026 |
| 8.0.0.18 | 343 | 3/23/2026 |
| 7.0.0.20 | 305 | 5/28/2026 |
| 7.0.0.19 | 344 | 3/23/2026 |
| 6.0.1.20 | 354 | 5/28/2026 |
| 6.0.1.19 | 398 | 3/23/2026 |