Как реализовать свойство CreatedAt с помощью замка ActiveRecord - PullRequest
2 голосов
/ 01 августа 2009

Скажем, я хочу создать класс с именем 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, или есть какой-то другой способ?

А как насчет свойства updatedAt?

Спасибо

1 Ответ

2 голосов
/ 01 августа 2009

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

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

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

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

Единственным недостатком этого метода является то, что ваши свойства CreatedAt и updatedAt должны всегда отражать то, что сохранено в БД, но в вашем случае вы устанавливаете свойства до , вы знаете, что фиксация в БД прошла успешно , Это неизбежно, но с некоторым кодом 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;
         }
   }
...