dotnetcore / dotnetcore/FreeSql
Aop 批量更新审计字段时统一使用相同值
- 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.