数据增删改与逻辑删除(Add / Update / Delete / LogicDelete)
IChameleonDbContext 的新增、更新、删除与逻辑删除方法用于对业务对象数据执行写操作。每个方法都提供同步与 Async 后缀的异步版本,编写 C# 脚本和微服务代码时一律使用异步版本。
概述
写操作的共同行为:
- 第一个参数
metaObjectCode是对象编码(如"LeaveApplication"),平台自动转换为实际表名(小写、.转_) - 写操作成功后会自动产生数据变更审计日志
- 审计字段(
createdby/createdtime/modifiedby/modifiedtime/organization/isdeleted)自动填充,无需手动赋值(ObjectData中已有值则不覆盖) - 返回值为受影响的行数(
int);批量操作传入空集合时直接返回0,不执行 SQL - 在事务中调用时,审计日志延迟到事务提交时统一写出,回滚时丢弃
API 方法
新增
// 异步版本(推荐)
Task<int> AddAsync(string metaObjectCode, ObjectData objectData);
Task<int> BatchAddAsync(string metaObjectCode, IEnumerable<ObjectData> objectDatas);
// 同步版本
int Add(string metaObjectCode, ObjectData objectData);
int BatchAdd(string metaObjectCode, IEnumerable<ObjectData> objectDatas);
| 参数 | 说明 |
|---|---|
metaObjectCode | 对象编码,如 "LeaveApplication" |
objectData / objectDatas | 数据对象(字典),键为小写字段编码 |
行为要点:
_id未赋值(Guid.Empty)时自动生成新的Guid;也可以显式传入_id- 自动填充
isdeleted = false、createdby(当前用户 ID)、createdtime(DateTimeOffset.UtcNow)、organization(上下文中的组织) - 返回受影响行数
更新
// 异步版本(推荐)
Task<int> UpdateAsync(string metaObjectCode, ObjectData objectData);
Task<int> BatchUpdateAsync(string metaObjectCode, IEnumerable<ObjectData> objectDatas);
// 同步版本
int Update(string metaObjectCode, ObjectData objectData);
int BatchUpdate(string metaObjectCode, IEnumerable<ObjectData> objectDatas);
行为要点:
objectData必须包含_id,否则抛ArgumentNullException;更新按_id定位,不能用条件批量更新字段- 只更新
ObjectData中出现的字段(部分更新),未出现的字段保持原值 - 自动填充
modifiedby/modifiedtime - 需要按条件批量改字段时,先查询出符合条件的
_id列表,再逐条更新,或使用平台接口的批量修改字段组件
删除(物理删除)
// 异步版本(推荐)
Task<int> DeleteAsync(string metaObjectCode, Guid id);
Task<int> BatchDeleteAsync(string metaObjectCode, Guid[] ids);
// 同步版本
int Delete(string metaObjectCode, Guid id);
int BatchDelete(string metaObjectCode, Guid[] ids);
物理删除会从数据库中彻底移除记录,不可恢复。除审计/合规要求外,业务数据删除应优先使用逻辑删除。
逻辑删除
// 异步版本(推荐)
Task<int> LogicDeleteAsync(string metaObjectCode, Guid id);
Task<int> BatchLogicDeleteAsync(string metaObjectCode, Guid[] ids);
// 同步版本
int LogicDelete(string metaObjectCode, Guid id);
int BatchLogicDelete(string metaObjectCode, Guid[] ids);
逻辑删除将 isdeleted 字段置为 true,数据仍在数据库中。注意:
- 后续查询不会自动排除已逻辑删除的数据,需要在过滤条件中显式加
FilterBuilder.Eq("isdeleted", false) - 已逻辑删除的数据如需恢复,用
UpdateAsync将isdeleted改回false
使用示例
新增并取回数据
var db = sdk.DbContext;
var entityCode = "LeaveApplication";
// 新增一条请假申请(_id 自动生成)
await db.AddAsync(entityCode, new ObjectData
{
{ "applicantid", context.UserId },
{ "leavetype", "年假" },
{ "startdate", DateTime.UtcNow },
{ "enddate", DateTime.UtcNow.AddDays(3) },
{ "status", "Pending" }
});
批量新增
var items = new List<ObjectData>();
foreach (var detail in details)
{
items.Add(new ObjectData
{
{ "orderid", orderId },
{ "productname", detail.Name },
{ "quantity", detail.Qty }
});
}
await db.BatchAddAsync("OrderItem", items);
查出再改(安全更新模式)
// 先查出,再基于完整数据修改,避免覆盖问题
var record = await db.GetByIdAsync(entityCode, id);
if (record != null)
{
record["status"] = "Approved";
await db.UpdateAsync(entityCode, record);
}
逻辑删除与恢复
// 逻辑删除
await db.LogicDeleteAsync(entityCode, id);
// 恢复
await db.UpdateAsync(entityCode, new ObjectData { { "_id", id }, { "isdeleted", false } });
注意事项
Update/BatchUpdate缺少_id会抛ArgumentNullException- 不要在
ObjectData中手动给createdby/createdtime/modifiedby/modifiedtime/organization赋常规业务值——它们是平台保留的审计字段 - 物理删除前如需留存记录,考虑先写入日志或使用逻辑删除
下一步
相关实现
- 同步实现:
chameleon-core/components/Chameleon.Database/DbContext/ChameleonDbContextOperation.cs - 异步实现:
chameleon-core/components/Chameleon.Database/DbContext/ChameleonDbContextOperationAsync.cs - 审计字段填充:
chameleon-core/components/Chameleon.Database/ChameleonDbHelper.cs的SetDefaultAddFields/SetDefaultUpdateFields