はじめに
.net coreのEntity Frameworkを使用していてタイムスタンプ(更新日時や作成日時)を複数のテーブルで簡単に扱えないか調べていたところ.NETのオフィシャルのドキュメントにイベントを使用する方法が書かれていましたので、こちらの解説を基本にした内容になります。
変更点
この例ではエンティティにCreatedAtとUpdatedAtのプロパティを追加します。UserエンティティはIhasTimestampsを実装しています。
model.cs
public interface IHasTimestamps
{
DateTime? UpdatedAt;
DateTime? CreatedAt;
}
public class User : IHasTimestamps
{
public int Id { get; set; }
public string? Name { get; set; }
public DateTime? UpdatedAt { get; set; }
public DateTime? CreatedAt { get; set; }
}
次にDbContextの方にイベントを追加して追加時と更新時に日時が設定されるようにします。
model.cs
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.ChangeTracking;
...
public class ApplicationContext : DbContext
{
public DbSet<User> Users { get; set; }
...
public ApplicationContext()
{
...
ChangeTracker.StateChanged += UpdateTimestamps;
ChangeTracker.Tracked += UpdateTimestamps;
}
private static void UpdateTimestamps(object? sender, EntityEntryEventArgs e)
{
if (e.Entry.Entity is IHasTimestamps entityWithTimestamps)
{
switch (e.Entry.State)
{
case EntityState.Modified:
entityWithTimestamps.UpdatedAt = DateTime.UtcNow;
break;
case EntityState.Added:
entityWithTimestamps.UpdatedAt = DateTime.UtcNow;
entityWithTimestamps.CreatedAt = DateTime.UtcNow;
break;
}
}
}
}
更新や追加のタイミングのイベントでIHasTimestampsが実装されているエンティティに対してUpdatedAtやCreatedAtを更新するようになっています。
タイムスタンプが必要なエンティティはIHasTimestampsを実装していけば良いので簡単に使えて良いですね。実は、もう一つ方法がありましたが、こちらはデータ追加時には良さそうなのですが、更新時にはトリガーなどを使用する必要がありましたのでイベントを使用する方が良さそうなのではないかと思いました。