I need to intercept the Save method, do some validations, alter some properties and then let it go again normally.
How can I do this?
Thanks! Alex
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
}
}
来源:https://stackoverflow.com/questions/1295842/how-to-intersept-the-save-method-on-activerecord-on-subsonic-orm