跳到主要内容

数据增删改与逻辑删除(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