How to intersept the save method on ActiveRecord on SubSonic ORM?

时光怂恿深爱的人放手 提交于 2019-12-04 11:02:05

I would recommend adding the following partial methods to be fired before their actual action:

OnSave(CancelEventArgs e); 
OnAdd(CancelEventArgs e); 
OnUpdate(CancelEventArgs e); 
OnDelete(CancelEventArgs e);

This isn't an event but I would use CancelEventArgs anyway, it's friendly, people know it and know how to use it and with it the actual action can be canceled from the partial methods.

These two should be added too to the list of the existing ones that fire after their actual action:

OnAdded(); 
OnUpdated();

I don't like that OnAdded() name but if Add was adopted instead of Insert then we must stick with it.

And that's it... With these partials I think we cover all the befores and afters of the actual data persistence methods giving us a greater flexibility to do whatever we want we our data.

I can implement this but I'm always afraid of touching the tt files because future updates will wipe off all my custom changes! :)

Thanks! Alex

In 2.x, there was a BeforeInsert and BeforeUpdate methods you could override.

I think you need to add an OnSaving method in the ActiveRecord.tt file. Place this next to the OnSaved() sig:

  partial void OnSaving();

Then update your ActiveRecord.tt file. 2 changes that I see:

Update the Update method

    public void Update(IDataProvider provider)
    {      
    <#if(tbl.Columns.Any(x=>x.Name=="ModifiedBy")){#>
        if(String.IsNullOrEmpty(this.ModifiedBy))
            this.ModifiedBy=Environment.UserName;
     <#}#>
    <#if(tbl.Columns.Any(x=>x.Name=="ModifiedOn")){#>
        this.ModifiedOn=DateTime.Now;
     <#}#>

       **OnSaving();**

        if(this._dirtyColumns.Count>0)
            _repo.Update(this,provider);
        OnSaved();
   }

and then update the Add method

public void Add(IDataProvider provider)
{ 
<#if(tbl.Columns.Any(x=>x.Name=="CreatedOn")){#>

            this.CreatedOn=DateTime.Now;
<#}#>
<#if(tbl.Columns.Any(x=>x.Name=="CreatedBy")){#>
            if(String.IsNullOrEmpty(this.CreatedBy))
                this.CreatedBy=Environment.UserName;
<#}#>
<#if(tbl.Columns.Any(x=>x.Name=="ModifiedOn")){#>
            this.ModifiedOn=DateTime.Now;
<#}#>
<#if(tbl.Columns.Any(x=>x.Name=="ModifiedBy")){#>
            if(String.IsNullOrEmpty(this.ModifiedBy))
                this.ModifiedBy=Environment.UserName;
<#}#>

            **OnSaving();**            

            var key=KeyValue();
            if(key==null){
                var newKey=_repo.Add(this,provider);
                this.SetKeyValue(newKey);
            }else{
                _repo.Add(this,provider);
            }
            SetIsNew(false);
            OnSaved();
}

Finally, you need to use your partial classes to override the OnSaving() method to update the values. I'm doing something very similar since I'm not using the convention of modifiedby and createdon (I have underscores there).

You can use the partial class mechanism to create your own version of Save which does validation and calls the SubSonic generated Save. e.g.

namespace YourNameSpace
{
   public partial class YourTable : IActiveRecord
   { 
       public void MySave()
       {
           // insert your validation here
           this.Save()
       }
   }
}

Each ActiveRecord class comes with a partial "OnSave()" method so all you need to do is create a partial and then override the partial OnSave() - just like in Linq To Sql:

public partial class MyClass{
   partial OnSave(){
   //magic
   }

}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!