2009-07-17 6 views
4

Le problème: Toutes les tables de notre base de données ont des champs CreatedDate, CreatedBy, ChangedDate, ChangedBy que je veux être définie automatiquement lors de la sauvegarde/Mise à jour d'une entité ActiveRecord. Mon premier essai a été de remplacer les méthodes Save() et Update(). Mais ces méthodes ne sont appelées que lorsque je fais une sauvegarde directe() ou une mise à jour() sur l'entité. Ils ne sont pas appelés dans un scénario Master - Detail où j'appelle Save() uniquement sur le maître.Howto remplir automatiquement les champs pendant la sauvegarde ou la mise à jour avec le château ActiveRecord

Ensuite, essayez les méthodes OnSave() et OnUpdate(), mais les changements dans les champs n'ont pas été conservés dans la base de données.

Enfin j'ai essayé la méthode BeforeSave(). Mais cette méthode n'est pas appelée lors de la mise à jour.

La question: Comment définir ces CreatedDate, CreatedBy, ChangedDate, champs ChangedBy automatiquement lors d'un enregistrement() ou mise à jour()?

Répondre

0

vous pouvez faire comme ce

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

Le problème avec cette approche est que la méthode Update() n'est appelée que lorsque la publication (dans votre exemple) est directement mise à jour. Mais lorsque j'apporte des modifications à la publication et que j'appelle Mise à jour sur le blog (qui contient beaucoup de messages), la méthode update() sur Post n'est pas appelée automatiquement. – Thomas

2

Pour modifier les données que vous vous voulez vous devez remplacer la méthode BeforeSave comme ceci:

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

Et enfin enregistrer votre exemple:

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

J'utilise généralement SaveCopy() pour utiliser la méthode redéfinie FindDirty (ID d'objet, IDictiona ry previousState, IDictionary currentState, NHibernate.Type.IType [] types) pour obtenir les valeurs précédentes de la classe.

Espérons que ça aide.

0

J'ai eu un même problème et a résolu le problème de cette façon:

J'utilise OnUpdate() et OnSave(). Comme vous l'avez mentionné, cette solution ne fonctionne pas avec les scénarios de détail principal. Pour cela, je définis explicitement le parent de chaque enfant. Notez les codes suivants:

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

Utilisez BeforeSave() pour l'enregistrement et OnFlushDirty() pour la mise à jour.

Questions connexes