Как реализовать свойство CreatedAt с помощью замка ActiveRecord

2

Скажем, я хочу создать класс EntityWithCreatedAt:

class Entity<T> : ActiveRecordBase<T>
{
  [PrimaryKey]
  public int Id { get; set; }
}

class EntityWithCreatedAt<T> : Entity<T>
{
  [Property]
  public DateTime CreatedAt { get; set; }
}

Каков наилучший способ заполнения поля CreatedAt? Я просто делаю это в конструкторах EntityWithCreatedAt, или есть какой-то другой способ?

Как насчет свойства UpdateAt?

Спасибо,

Теги:
castle-activerecord

1 ответ

2
Лучший ответ

В Rails-реализации AR, CreatedAt и UpdAt - это автоматические временные метки, созданные при миграции (хотя их также можно создать вручную). Предполагая, что вы хотите такого же поведения, вам необходимо переопределить Create и Update.

   public override void Update() 
   {
         UpdatedAt = DateTime.Now;                      
         base.Update(); 
   }

   public override void Create()
   {
         CreatedAt = DateTime.Now;
         base.Create();
   }

Если вы не используете назначенный первичный ключ, и БД его генерирует для вас (например, с автоматическим приращением), вы можете использовать метод "Сохранить", чтобы решить, следует ли вызывать "Создать" или "Обновить". Использование "Сохранить" по-прежнему отлично работает для вас, так как вызов метода "Сохранить() базового класса вызовет вызов вашего" Создать "(если идентификатор не был установлен) или" Обновление "(если идентификатор установлен и запись ранее была сохранена).

Единственным недостатком этого метода является то, что ваши свойства CreateAt и UpdateAt всегда должны отражать то, что сохраняется в БД, но в вашем случае вы устанавливаете свойства, прежде чем знаете, что фиксация в БД преуспела. Это неизбежно, но с некоторым кодом try/catch в вашем переопределении обновления вы должны иметь возможность записать предыдущее значение и назначить его обратно, если что-то пойдет не так:

   public override void Update() 
   {
         DateTime originalUpdatedAt = UpdatedAt;
         try 
         {
            UpdatedAt = DateTime.UtcNow;  // Assuming you're using UTC timestamps (which I'd recommend)                     
            base.Update(); 
         }
         catch  // Don't worry, you're rethrowing so nothing will get swallowed here.
         {
            UpdatedAt = originalUpdatedAt;
            throw;
         }
   }

Ещё вопросы

Сообщество Overcoder
Наверх
Меню