如何使用 Castle ActiveRecord 在保存或更新过程中自动填充字段

发布于 2024-07-27 01:18:38 字数 482 浏览 5 评论 0原文

问题: 我们数据库中的所有表都有 CreatedDate、CreatedBy、ChangedDate、ChangedBy 字段,我希望在保存/更新 ActiveRecord 实体时自动设置这些字段。

我的第一次尝试是重写 Save() 和 Update() 方法。 但只有当我对实体执行直接 Save() 或 Update() 操作时,才会调用这些方法。 它们不会在主 - 详细信息场景中被调用,在该场景中我仅在主上调用 Save() 。

接下来尝试的是 OnSave() 和 OnUpdate() 方法,但此处字段中的更改未保留在数据库中。

最后我尝试了BeforeSave()方法。 但更新时不会调用该方法。

问题: 如何在 Save() 或 Update() 期间自动设置这些 CreatedDate、CreatedBy、ChangedDate、ChangedBy 字段?

The Problem:
All tables in our database have CreatedDate, CreatedBy, ChangedDate, ChangedBy fields which I want to be set automatically when Saving / Updating an ActiveRecord entity.

My first try was to override the Save() and Update() methods. But these methods only get called when I do a direct Save() or Update() on the entity. They are not being called in a Master - Detail scenario where I call Save() only on the master.

Next try were the OnSave() and OnUpdate() methods, but here changes in the fields were not persisted in the database.

Finally I tried the BeforeSave() method. But this method is not called when updating.

The Question:
How can set these CreatedDate, CreatedBy, ChangedDate, ChangedBy fields automatically during a Save() or Update()?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

如日中天 2024-08-03 01:18:39

你可以这样做

[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();            
    }

you could do like this

[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();            
    }
行至春深 2024-08-03 01:18:39

我遇到了同样的问题并以这种方式解决了它:

我使用 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();
}

I had a same problem and solved it this way:

I use OnUpdate() and OnSave(). As you mentioned this solution does not work with master detail scenarios. For this I set parent of each child explicitly. Note following codes:

[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();
}
女皇必胜 2024-08-03 01:18:38

要根据需要修改数据,您必须重写 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(object id, IDictionary previousState, IDictionary currentState, NHibernate.Type .IType[] 类型)来获取该类的先前值。

希望能帮助到你。

To modify data as you you want you have to override the BeforeSave method like this:

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

And finally save your instance:

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);
    }
}

I usually use SaveCopy() to make use of the overriden method FindDirty(object id, IDictionary previousState, IDictionary currentState, NHibernate.Type.IType[] types) to get the previous values of the class.

Hope it helps.

千年*琉璃梦 2024-08-03 01:18:38

使用 BeforeSave() 进行保存,使用 OnFlushDirty() 进行更新。

Use BeforeSave() for saving and OnFlushDirty() for updating.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文