Entity Framework: настройка временной отметки времени

Все наши таблицы базы данных имеют UpdateUserID и UpdateTS. Я хотел бы иметь этот набор, если моя сущность имеет изменения. Есть ли способ, которым я могу получить это обновление на месте условно?

Если я вручную установлю UpdateTS в коде, тогда он скажет, что мой объект изменился и всегда будет обновлять объект.

Ответ 1

Вы должны иметь возможность обрабатывать событие SavingChanges (пример здесь) и выполнять логику, как описано @sander

Ответ 2

Я вызываю этот метод расширения перед вызовом context.SaveChanges():

public static void SetLastModified(this ObjectContext context, DateTime dateTime)
{
    DateTime now = DateTime.UtcNow;
    foreach (ObjectStateEntry entry in context.ObjectStateManager.GetObjectStateEntries(EntityState.Modified))
    {
        if (!entry.IsRelationship)
        {
            IHasLastModified lastModified = entry.Entity as IHasLastModified;
            if (lastModified != null)
                lastModified.LastModified = now;
        }
    }
}

Я могу легко вызвать этот код, потому что я обертываю ObjectContext в классе репозитория. Если вы используете его голым, вы можете подключить событие ObjectContext.SavingChanges, чтобы сделать что-то подобное.

Ответ 3

Здесь реализована реализация двух других идей со следующими соображениями:

  • Перед вызовом SaveChanges() убедитесь, что вы либо создаете прокси-серверы, которые автоматически обнаруживают изменения, либо вручную обнаруженные изменения. Если нет, состояние объекта будет EntityState.Unmodified, и последняя измененная временная метка не будет обновлена.
  • Я расширил код, чтобы установить последнюю измененную метку времени, когда объект сначала создан (EntityState.Added)

Код

public interface IHasLastModified
{
    DateTime? LastModified { get; set; }
}

public class MyClass : IHasLastModified
{
    public virtual int Id { get; set; }

    public virtual string SomeOtherProperty { get; set; }

    public virtual DateTime? LastModified { get; set; }
}

public class MyContext : DbContext
{
    public override int SaveChanges()
    {            
        DateTime now = DateTime.UtcNow;
        foreach (ObjectStateEntry entry in (this as IObjectContextAdapter).ObjectContext.ObjectStateManager.GetObjectStateEntries(EntityState.Added | EntityState.Modified))
        {
            if (!entry.IsRelationship)
            {
                IHasLastModified lastModified = entry.Entity as IHasLastModified;
                if (lastModified != null)
                    lastModified.LastModified = now;
            }
        }

        return base.SaveChanges();
    }