2009-08-18 10 views
4

J'ai besoin d'intercepter la méthode Save, de faire quelques validations, de modifier certaines propriétés et de les relancer normalement.Comment intercepter la méthode save sur ActiveRecord?

Comment est-ce que je peux faire ceci?

Merci! Alex

+3

ActiveRecord est un joli en-tête "générique".Il y a une bibliothèque O/RM beaucoup plus largement utilisée (et beaucoup dit mieux) utilisant aussi le mot; "ActiveRecord", probablement en raison du motif de conception Martin Fowler inventé il y a plusieurs années portant ce nom. Donc, même si vous avez marqué le message pour que les gens puissent comprendre que c'est Subsonic dont vous parlez, plus correctement serait également d'ajouter Subsonic dans l'en-tête ... –

+0

Vous avez raison ... complètement oublié le "générique" l'environnement stackoverflow est. Ne se reproduira plus :) – AlexCode

Répondre

4

Je recommande d'ajouter les méthodes partielles suivantes à cuire avant de leur action réelle:

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

Ce n'est pas un événement, mais je voudrais utiliser CancelEventArgs de toute façon, il est amical, les gens le savent et k maintenant comment l'utiliser et avec elle l'action réelle peut être annulée à partir des méthodes partielles.

Ces deux éléments doivent être ajoutés aussi à la liste de celles existantes que le feu après leur action réelle:

OnAdded(); 
OnUpdated(); 

Je n'aime pas ce nom OnAdded() mais si Ajouter a été adoptée au lieu de Insérer puis nous devons rester avec.

Et c'est tout ... Avec ces partiels, je pense que nous couvrons tous les avantages et les inconvénients des méthodes actuelles de persistance des données nous donnant une plus grande flexibilité pour faire ce que nous voulons nos données.

Je peux implémenter ceci mais j'ai toujours peur de toucher les fichiers tt car les futures mises à jour effaceront toutes mes modifications personnalisées! :)

Merci! Alex

0

Vous pouvez utiliser le mécanisme de classe partielle pour créer votre propre version de Save qui effectue la validation et appelle la sauvegarde générée par SubSonic. par exemple.

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

Salut mec, merci pour la réponse. Ce n'est pas vraiment une bonne option car il est facile d'oublier qu'il existe une sauvegarde personnalisée et d'utiliser la valeur par défaut d'ActiveRecord. Je n'ai pas besoin d'une surcharge, j'ai besoin de quelque chose comme une méthode OnSave (expéditeur d'objet, CancelEventArgs e) où je peux valider, modifier ou même annuler le processus de sauvegarde indépendamment de la surcharge de sauvegarde que j'utilise. Je demandais parce que je pourrais manquer quelque chose mais sinon je devrais mettre en application si moi-même. – AlexCode

0

Chaque classe ActiveRecord est livré avec une méthode partielle « OnSave() » tout ce que vous devez faire est de créer une partie, puis remplacer la OnSave partielle() - comme dans Linq sql:

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

} 
+0

Salut Rob, merci pour la réponse. Le fait est que la méthode partielle disponible est OnSaved() qui indique qu'elle est appelée après les instructions Save(). Quand cela est-il réellement déclenché, avant ou après l'enregistrement réel()? Merci! Alex – AlexCode

+0

Je l'ai vu sur le code ... il est appelé à la fin des méthodes Add & Update et cela ne résout pas mon problème. Je dois modifier les données d'entité avant de les enregistrer. Je vais ajouter une solution possible car les commentaires ne peuvent contenir que 600 caractères. – AlexCode

1

Dans 2.x, il existait des méthodes BeforeInsert et BeforeUpdate que vous pouviez remplacer.

Je pense que vous devez ajouter une méthode OnSaving dans le fichier ActiveRecord.tt. Placez ce côté du sig OnSaved():

partial void OnSaving(); 

Ensuite, mettre à jour votre fichier ActiveRecord.tt. 2 changements que je vois:

Mise à jour de la méthode de mise à jour

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

, puis mettre à jour la méthode 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(); 
} 

Enfin, vous devez utiliser vos classes partielles pour remplacer la méthode OnSaving() mettre à jour les valeurs. Je fais quelque chose de très similaire puisque je n'utilise pas la convention de modifiedby et createdon (j'ai souligné ici).

+0

Ouais ... c'est presque ça. Je ne l'ai pas encore fait parce que j'ai "peur" des futures mises à jour subsonic tt Comment gérez-vous vos changements personnalisés Une autre chose est que je dois être en mesure d'annuler les changements avant l'action réelle donc j'ai besoin de CancelEventArgs sur les méthodes On * – AlexCode

+0

Vous n'avez pas vraiment le choix, si vous en avez besoin, alors vous allez devoir éditer les fichiers tt. les modèles par défaut, aussi (quelque chose de similaire était présent dans la version précédente, il y a donc une chance qu'il soit accepté) Vous pouvez poster un problème sur le site SubSonic github (sous le projet subsonic-3/templates). Je n'aime pas éditer les fichiers tt non plus (je préfère m'en tenir à des classes partielles quand c'est possible), mais si vous en avez besoin, alors vous allez devoir le faire. –

+0

Puisque vous devez l'annuler, avez-vous cherché une méthode de validation? Il existait dans 2.x et je pense qu'il a été appelé avant le démarrage des commandes Insert/Update. Je pense qu'il y avait un moyen pour vous d'annuler l'insertion/mise à jour en le rendant invalide. Je suis nouveau à 3, donc je n'ai que la version précédente pour le comparer. –

Questions connexes