我已经从
SavingChangesAsync
接口实现了 ISaveChangesInterceptor
。我无法确定正在保存的记录的主键,因为它尚未提交。我也尝试了SavedChangesAsync
功能,但是实体状态没有设置为Added
,而是Unchanged
。
我尝试了以下方法:
public async ValueTask<InterceptionResult<int>> SavingChangesAsync(DbContextEventData eventData, InterceptionResult<int> result, CancellationToken cancellationToken = default)
{
var entry eventData.Context!.ChangeTracker.Entries().FirstOrDefault()
console.write(entry.State); //equals Added
console.write(entry.IsKeySet); //equals false
console.write(entry.Entity.Id); //equals 0
return await new ValueTask<int>(result);
}
记录的下一个主键值尚未设置。我也用过:
public async ValueTask<int> SavedChangesAsync(SaveChangesCompletedEventData eventData, int result, CancellationToken cancellationToken = default)
{
var entry eventData.Context!.ChangeTracker.Entries().FirstOrDefault()
console.write(entry.State); //equals Unchanged
console.write(entry.IsKeySet); //equals true
console.write(entry.Entity.Id); //equals next integer value
return await new ValueTask<int>(result);
}
我无法使用新 id 触发第一个事件,也无法使用状态值为
Added
触发第二个事件
这是处理数据库生成的标识列时的预期行为。在
SavingChanges
时,您可以查询更改跟踪器以查看添加、更新或删除的内容。在 SavedChanges 时,更改已提交,因此更改跟踪器会将它们报告为未修改。
这意味着,如果您想记录有关实体的信息并在插入时包含其结果 ID,则需要缓存对添加的实体的引用以及任何“预提交”状态(如果您在 SavingChanges 事件处理程序期间记录该内容) 。然后在
SavedChanges
处理程序中,从缓存的引用中获取 Id 和详细信息:
private class EntityChangeInfo
{
public EntityState State { get; set; }
public EntityEntry Entry { get; set; }
// This is where you can add things like field data for updates, old value / updated value, etc.
}
private List<EntityChangeInfo> _entityChanges = new();
...然后在 SavingChanges() 中
_entityChanges.Clear();
var entry eventData.Context!.ChangeTracker.Entries().FirstOrDefault()
_entityChanges.Add(new EntityChangeInfo { entry.State, entry });
return await new ValueTask<int>(result);
然后在SavedChanges()中
foreach(var entityChange in _entityChanges)
{
console.write(entityChange.State); // Original state when saving
console.write(entityChange.Entry.Id); equals key that was assigned
}
_entityChanges.Clear();
在提交之前尝试获取 ID 的麻烦在于,这只能通过 EF 在数据库使用的序列上应用并发锁来完成,从您查询下一个可用的时间开始ID 是,并且正在提交更改。这会带来问题,因为您可以获得 ID 值,但提交实际上会失败。因此,仅应在提交发生后才对此进行报告/审核。