dotnetcore / dotnetcore/FreeSql

Aop 批量更新审计字段时统一使用相同值

Open
#2,236 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
C#
Stars
4.4k
Forks
910
PR merge metrics
No merged PRs in 30d

Description

---

```markdown

#### Feature 特性

批量执行 `InsertOrUpdate().SetSource(entities)` 时,当通过 `Aop.AuditValue` 设置的更新字段值在所有实体中均相同,期望生成统一的 `SET` 赋值,而非为每个实体生成独立的 `CASE WHEN` 分支。

**当前生成的 SQL:**
```sql
UPDATE [Table]
SET [UpdateTime] = CASE [Id]
WHEN 178493 THEN '2026-04-29 14:47:11.015'
WHEN 178494 THEN '2026-04-29 14:47:11.016'
WHEN 178495 THEN '2026-04-29 14:47:11.017'
END
WHERE [Id] IN (178493, 178494, 178495)
```

**期望生成的 SQL:**
```sql
UPDATE [Table]
SET [UpdateTime] = '2026-04-29 14:47:11.015'
WHERE [Id] IN (178493, 178494, 178495)
```

#### 简要描述原因

在 `Aop.AuditValue` 事件中对 `AuditValueType.Update` 统一赋值时(如设置更新时间 `DateTime.Now`),所有实体的该字段值实际上是相同的。

但 FreeSql 当前会为每个实体执行AOP代码的时候`UpdateTime` 都不一样, 导致生成独立的 `CASE WHEN` 分支,导致以下问题:

1. SQL 体积随批量数量线性膨胀,影响传输和执行效率
2. `CASE WHEN` 需要数据库逐行判断,无额外收益
3. 毫秒级时间差导致同一批次数据审计时间不一致

建议:当 `AuditValue` 事件中设置的值对所有实体相同时,自动优化为统一赋值;或提供配置项让开发者显式标记"该审计字段为批量统一值"。

#### 使用场景

批量更新时自动维护审计字段,如:

```csharp
// AOP 统一设置审计值
freeSql.Aop.AuditValue += (_, e) =>
{
if (e.AuditValueType == AuditValueType.Update)
{
e.Value = e.Column.CsName switch
{
"UpdateTime" => DateTime.Now,
_ => e.Value
};
}
};

// 批量插入或更新
await freeSql.Update()
.SetSource(entities)
.ExecuteAffrowsAsync();
```

期望批量字段值统一时,通过AOP修改的审计字段生成的 SQL 能自动优化为单一赋值,减少 SQL 体积并提升执行效率。
```

---

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.