Как автоматически заполнять поля при сохранении или обновлении с помощью Castle ActiveRecord - PullRequest
4 голосов
/ 17 июля 2009

Проблема: Все таблицы в нашей базе данных имеют поля CreatedDate, CreatedBy, ChangedDate, ChangedBy, которые я хочу установить автоматически при сохранении / обновлении объекта ActiveRecord.

Моей первой попыткой было переопределение методов Save () и Update (). Но эти методы вызываются только тогда, когда я выполняю прямую Save () или Update () для объекта. Они не вызываются в сценарии Master - Detail, где я вызываю Save () только для мастера.

Следующей попыткой были методы OnSave () и OnUpdate (), но здесь изменения в полях не были сохранены в базе данных.

Наконец я попробовал метод BeforeSave (). Но этот метод не вызывается при обновлении.

Вопрос: Как можно автоматически установить эти поля CreatedDate, CreatedBy, ChangedDate, ChangedBy во время сохранения () или обновления ()?

Ответы [ 4 ]

2 голосов
/ 02 февраля 2010

Чтобы изменить данные так, как вы хотите, вы должны переопределить метод BeforeSave следующим образом:

    protected override bool BeforeSave(IDictionary state)
    {
        bool retval = base.BeforeSave(state);
        state["Password"] = Global.Encrypt("password");
        return retval;
    }

И, наконец, сохраните свой экземпляр:

protected void btnSave_Click(object sender, EventArgs e)
{
    try
    {
        qfh.User user = null;

        user = new qfh.User();

        user.UserName = txtUserName.Text;
        user.Name = txtName.Text;
        user.IsAdministrator = cboIsAdministrador.SelectedValue == "Yes";
        user.IsActive = cboIsActive.SelectedValue == "Yes";

        user.SaveCopy();
    }
    catch (Exception ex)
    {
        ex = Utilities.GetInnerException(ex);
        JSLiteral.Text = Utilities.GetFormattedExceptionMessage(ex);
    }
}

Я обычно использую SaveCopy (), чтобы использовать переопределенный метод FindDirty (типы объектов, типы IDictionary previousState, IDictionary currentState, NHibernate.Type.IType []) для получения предыдущих значений класса.

Надеюсь, это поможет.

1 голос
/ 06 сентября 2010

Используйте BeforeSave () для сохранения и OnFlushDirty () для обновления.

0 голосов
/ 13 июля 2010

У меня была такая же проблема, и я решил ее следующим образом:

Я использую OnUpdate() и OnSave(). Как вы упомянули, это решение не работает с основными сценариями детализации. Для этого я устанавливаю родителя каждого ребенка явно. Обратите внимание на следующие коды:

[ActiveRecord(Lazy = true)]
public class Lookup : ActiveRecordBase<Lookup>
{
    [HasMany(typeof(LookupItem), Cascade = ManyRelationCascadeEnum.All)]
    public virtual IList Items { set; get; }

    //other properties...
}


[ActiveRecord(Lazy = true)]
public class LookupItem : ActiveRecordBase<LookupItem>
{
    [BelongsTo("Lookup_id")]
    public virtual Lookup ContainerLookup { set; get; }

    //other properties...
}

void SaveLookup()
{
    Lookup lookup = GetLookup();
    LookupItem lookupItem = new LookupItem()
    {
        Title = LookupItemName,
        ContainerLookup = lookup
    };
    lookup.Items.Add(lookupItem);
    lookup.Save();
}
0 голосов
/ 23 июля 2009

вы могли бы сделать это

[ActiveRecord("PostTable")]
public class Post : ActiveRecordBase<Post>
{
     private int _id;
     private DateTime _created;

     [PrimaryKey]
     public int Id
     {
        get { return _id; }
        set { _id = value; }
     }

     [Property("created")]
     public DateTime Created
     {
        get { return _created; }
        set { _created = value; }
     }

     private void BeforeUpdate()
     {
        // code that run before update
        Created = DateTime.Now;
     }

    public override void Update()
    {
        BeforeUpdate();
        base.Update();            
    }
...