Предполагая, что вы определили теневое свойство LastModified
для каждой сущности, для которой вы хотите эту функциональность, как в вашем примере
builder.Property<DateTime>("LastUpdated");
и вопрос в том, как обновить его автоматически.
Техника, описанная в ответе Давида, устарела. Все еще возможно переопределить SaveChanges
(и SaveChangesAsync
), но есть ИМХО лучший подход, показанный в Автоматически заполнять и создавать в EF Core . Это интерфейсный подход, но его можно легко настроить для свойства shadow (или любого свойства - используемые методы работают как для shadow, так и для явных свойств).
Краткий обзор: начиная с версии 2.1 EF Core предоставляет События изменения состояния :
Новые Tracked
и StateChanged
события на ChangeTracker
могут использоваться для записи логики, которая реагирует на объекты, входящие в DbContext
или изменяющие их состояние.
Вот как вы можете их использовать. Добавьте следующее в ваш производный контекстный класс:
void SubscribeStateChangeEvents()
{
ChangeTracker.Tracked += OnEntityTracked;
ChangeTracker.StateChanged += OnEntityStateChanged;
}
void OnEntityStateChanged(object sender, EntityStateChangedEventArgs e)
{
ProcessLastModified(e.Entry);
}
void OnEntityTracked(object sender, EntityTrackedEventArgs e)
{
if (!e.FromQuery)
ProcessLastModified(e.Entry);
}
void ProcessLastModified(EntityEntry entry)
{
if (entry.State == EntityState.Modified || entry.State == EntityState.Added)
{
var property = entry.Metadata.FindProperty("LastModified");
if (property != null && property.ClrType == typeof(DateTime))
entry.CurrentValues[property] = DateTime.UtcNow;
}
}
и добавьте
SubscribeStateChangeEvents();
к вашему производному контекстному конструктору (ам).
И это все. Как только контекст подписан на эти события, он будет уведомлен в любое время, когда сущность изначально отслеживается или ее состояние изменяется. Вас интересует только состояние Modified
и Added
, не вызванное материализацией запроса (если вам не нужен Added
, просто исключите его из условия if
). Затем вы проверяете, содержит ли объект свойство DateTime LastModified
, используя службы метаданных EF Core, и если да, просто обновите его с текущей датой / временем.