之前我們有介紹過 Entity Framework Core 7 紀錄整個系統的資料變更 詳記示範,本篇要介紹的是在每個資料表中都加上建立時間和修改時間,當資料建立和修改時就會自動更新時間欄位的方式。
首先在資料庫的部分逃不了,每個資料表都需要加上這兩個欄位:
建立一個介面,把所有要加上這兩個時間的資料庫對應實體都繼承這個介面:
建立一個自訂的儲存攔截器,繼承 SaveChangesInterceptor ,然後覆寫 SavingChanges 和 SavingChangesAsync 方法。只要變更的實體是繼承 IEntity ,就要依據是建立還是更新來填入建立和更新日期。
最後在 ApplicationDbContext 中的 OnConfiguring 加上攔截器即可。
參考資料:
Microsoft.Learn - SaveChangesInterceptor Class
首先在資料庫的部分逃不了,每個資料表都需要加上這兩個欄位:
create table MyTable
(
CreatedAt datetime default getdate() not null,
UpdatedAt datetime default getdate() not null
)
建立一個介面,把所有要加上這兩個時間的資料庫對應實體都繼承這個介面:
public interface IEntity
{
[Column(TypeName = "datetime")] DateTime CreatedAt { get; set; }
[Column(TypeName = "datetime")] DateTime UpdatedAt { get; set; }
}
建立一個自訂的儲存攔截器,繼承 SaveChangesInterceptor ,然後覆寫 SavingChanges 和 SavingChangesAsync 方法。只要變更的實體是繼承 IEntity ,就要依據是建立還是更新來填入建立和更新日期。
public class TimestampsSaveChangesInterceptor : SaveChangesInterceptor
{
public override InterceptionResult<int> SavingChanges(DbContextEventData eventData, InterceptionResult<int> result)
{
SetEntityDateTime(eventData);
return base.SavingChanges(eventData, result);
}
public override ValueTask<InterceptionResult<int>> SavingChangesAsync(
DbContextEventData eventData, InterceptionResult<int> result,
CancellationToken cancellationToken = new CancellationToken()
)
{
SetEntityDateTime(eventData);
return base.SavingChangesAsync(eventData, result, cancellationToken);
}
private void SetEntityDateTime(DbContextEventData eventData)
{
if (eventData.Context == null) return;
var entries = eventData.Context.ChangeTracker.Entries();
foreach (var entry in entries)
{
if (entry.Entity is not IEntity entity) continue;
if (entry.State == EntityState.Added)
{
entity.CreatedAt = DateTime.UtcNow;
entity.UpdatedAt = DateTime.UtcNow;
}
else if (entry.State == EntityState.Modified)
{
entity.UpdatedAt = DateTime.UtcNow;
}
}
}
}
最後在 ApplicationDbContext 中的 OnConfiguring 加上攔截器即可。
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
=> optionsBuilder.UseSqlServer("Name=ConnectionStrings:DefaultConnection")
.AddInterceptors(new TimestampsSaveChangesInterceptor());
參考資料:
Microsoft.Learn - SaveChangesInterceptor Class
留言
張貼留言
如果有任何問題、建議、想說的話或文章題目推薦,都歡迎留言或來信: a@ruyut.com