2009-07-17 4 views
4

Das Problem: Alle Tabellen in unserer Datenbank haben CreatedDate, CreatedBy, ChangedDate, ChangedBy Felder, die ich möchte automatisch eingestellt werden, wenn Speichern/Aktualisieren einer Entität Active.Howto automatisch füllen Felder beim Speichern oder Update mit Schloss Active

Mein erster Versuch war, die Save() und Update() Methoden zu überschreiben. Aber diese Methoden werden nur aufgerufen, wenn ich eine direkte Save() oder Update() für die Entität mache. Sie werden nicht in einem Master-Detail-Szenario aufgerufen, in dem ich Save() nur auf dem Master aufruft.

Nächster Versuch waren die Methoden OnSave() und OnUpdate(), aber hier wurden Änderungen in den Feldern in der Datenbank nicht beibehalten.

Schließlich versuchte ich die BeforeSave() Methode. Diese Methode wird jedoch beim Aktualisieren nicht aufgerufen.

Die Frage: Wie diese CreatedDate gesetzt, CreatedBy, ChangedDate, ChangedBy Felder automatisch während eines Save() oder Update()?

Antwort

0

Sie dieses

[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

Das Problem mit diesem Ansatz ist, dass die Update() -Methode nur aufgerufen wird, wenn die Post (in Ihrem Beispiel) direkt aktualisiert wird. Aber wenn ich Änderungen an der Post und rufen Sie Update auf dem Blog (mit vielen Posts) die update() -Methode auf Post ist nicht automatisch aufgerufen. – Thomas

2

tun könnten Daten, wie Sie ändern Sie Sie die Before Methode wollen wie dies außer Kraft setzen müssen:

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

Und schließlich Instanz speichern:

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

Normalerweise verwende ich SaveCopy(), um die Methode findDirty (Objekt ID, IDicta ry previousState, IDictionary currentState, NHibernate.Type.IType [] types), um die vorherigen Werte der Klasse zu erhalten.

Ich hoffe, es hilft.

0

hatte ich ein gleiches Problem und es auf diese Weise gelöst:

I OnUpdate() und OnSave() verwenden. Wie Sie erwähnt haben, funktioniert diese Lösung nicht mit Master-Detailszenarien. Dazu setze ich Eltern jedes Kindes explizit. Beachten Sie folgende Codes:

[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

Verwenden Sie BeforeSave() zum Speichern und OnFlushDirty() zum Aktualisieren.

Verwandte Themen