Subsonic 如何在亚音速ORM上使用ActiveRecord的保存方法?

Subsonic 如何在亚音速ORM上使用ActiveRecord的保存方法?,subsonic,subsonic3,subsonic-active-record,Subsonic,Subsonic3,Subsonic Active Record,我需要截取Save方法,进行一些验证,修改一些属性,然后让它正常运行 我该怎么做 谢谢! Alex您可以使用部分类机制创建您自己的Save版本,该版本进行验证并调用亚音速生成的Save。e、 g namespace YourNameSpace { public partial class YourTable : IActiveRecord { public void MySave() { // insert your validat

我需要截取Save方法,进行一些验证,修改一些属性,然后让它正常运行

我该怎么做

谢谢!
Alex

您可以使用部分类机制创建您自己的Save版本,该版本进行验证并调用亚音速生成的Save。e、 g

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

每个ActiveRecord类都附带一个partial“OnSave()”方法,因此您只需创建一个partial,然后重写partial OnSave()-就像在Linq to Sql中一样:

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

}

我建议在实际操作之前添加以下要触发的部分方法:

OnSave(CancelEventArgs e); 
OnAdd(CancelEventArgs e); 
OnUpdate(CancelEventArgs e); 
OnDelete(CancelEventArgs e);
OnAdded(); 
OnUpdated();
这不是一个事件,但无论如何我都会使用CancelEventArgs,它很友好,人们知道并知道如何使用它,通过它可以从partial方法中取消实际操作

这两项也应添加到现有的实际行动后开火的武器清单中:

OnSave(CancelEventArgs e); 
OnAdd(CancelEventArgs e); 
OnUpdate(CancelEventArgs e); 
OnDelete(CancelEventArgs e);
OnAdded(); 
OnUpdated();
我不喜欢OnAdded()名称,但如果采用Add而不是Insert,那么我们必须坚持使用它

就这样。。。通过这些部分,我认为我们涵盖了实际数据持久化方法的所有之前和之后的内容,从而使我们能够更灵活地处理数据

我可以实现这一点,但我总是害怕触碰tt文件,因为将来的更新将删除我所有的自定义更改!:)

谢谢!
Alex在2.x中,有一个BeforeInsert和BeforeUpdate方法可以覆盖

我认为您需要在ActiveRecord.tt文件中添加一个OnSaving方法。将其放在OnSaved()标志旁边:

然后更新ActiveRecord.tt文件。我看到的两个变化:

更新更新方法

    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();
   }
公共作废更新(IDataProvider提供程序)
{      
x、 Name==“ModifiedBy”){#>
if(String.IsNullOrEmpty(this.ModifiedBy))
this.ModifiedBy=Environment.UserName;
x、 Name==“ModifiedOn”){#>
this.ModifiedOn=DateTime.Now;
**OnSaving()**
如果(此._dirtyColumns.Count>0)
_回购更新(本,提供方);
OnSaved();
}
然后更新Add方法

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();
}
public void Add(IDataProvider提供程序)
{ 
x、 名称==“CreatedOn”){#>
this.CreatedOn=DateTime.Now;
x、 名称==“CreatedBy”){#>
if(String.IsNullOrEmpty(this.CreatedBy))
this.CreatedBy=Environment.UserName;
x、 Name==“ModifiedOn”){#>
this.ModifiedOn=DateTime.Now;
x、 Name==“ModifiedBy”){#>
if(String.IsNullOrEmpty(this.ModifiedBy))
this.ModifiedBy=Environment.UserName;
**OnSaving();**
var key=KeyValue();
if(key==null){
var newKey=_repo.Add(这个,提供者);
此.SetKeyValue(newKey);
}否则{
_补充回购协议(本协议,提供方);
}
SetIsNew(假);
OnSaved();
}

最后,您需要使用分部类重写OnSaving()方法来更新值.

嗨,伙计,谢谢你的回复。这不是一个好的选择,因为很容易忘记有一个自定义的保存并使用ActiveRecord默认值。我不需要重载,我需要像OnSave(对象发送器,CancelEventArgs e)这样的东西方法,在该方法中,我可以独立于正在使用的保存重载来验证、更改甚至取消保存过程。我之所以这样问是因为我可能会遗漏一些内容,但如果没有,我将不得不自己实现。嗨,Rob,谢谢你的回答。问题是可用的部分方法是OnSaved(),它指示在保存()之后调用实际保存()之前或之后,实际何时触发?谢谢!AlexI在代码中看到了它…它是在添加和更新方法的末尾调用的,这并不能解决我的问题。我需要在保存实体数据之前修改它。我将添加一个可能的解决方案,因为这里的注释只能有600个字符。ActiveRecord是一个非常“通用”的标题。有一个更广泛的使用(很多人说更好)O/RM库也使用“ActiveRecord”一词,可能是由于马丁·福勒几年前创造的带有该名称的设计模式。因此,即使你给帖子贴上标签,以便人们能够理解你所说的亚音速,更正确的做法是在标题中加上亚音速…你是对的…完全忘记了“通用”环境堆栈溢出是。不会再发生:)是的……差不多了。我只是还没做,因为我"害怕未来的亚音速tt更新。你如何处理你的自定义更改?另一件事是,我需要能够在实际操作之前取消更改,因此我需要on*方法上的CancelEventArgs。你真的没有选择。如果你需要,那么你将不得不编辑tt文件。我想看看OnSaving也添加了默认模板(类似于上一版本中的内容,因此它可能会被接受)。您可以在亚音速github网站(亚音速-3/模板项目下)发布一个问题。它可能会在以后的版本中被审查和添加。我也不喜欢编辑tt文件(如果可能的话,我宁愿坚持只制作部分类),但是如果你需要它工作,那么你就必须这样做。既然你需要取消它,你找过验证方法吗?它曾经存在于2.x中,我想它是在Insert/Update命令开始之前调用的。我想有一种方法可以通过将它设置为无效来取消Insert/Update。我是3的新手,所以我只有previo与之比较的美国版本。