2 Stimmen

Prüfung von NHibernate-Arbeitseinheiten mit Erstellungs-/Aktualisierungsdatum

Ich verwende die Methode von Ayende ( http://ayende.com/Blog/archive/2009/04/29/nhibernate-ipreupdateeventlistener-amp-ipreinserteventlistener.aspx ), um das Erstellungs- und Aktualisierungsdatum für Entitäten mit Listenern zu setzen, aber es setzt sie nur für die betroffene Entität, nicht für irgendetwas anderes in der Unit of Work.

Wenn ich also zum Beispiel dies tue:

Order order = repository.Get<Order>(1);
order.AddNote(new Note("this is a note"));
repository.SaveOrUpdate(order);

Die Notiz erhält ein Erstellungs-/Aktualisierungsdatum, der Auftrag jedoch nicht. Gibt es irgendwelche Tricks, damit die gesamte Arbeitseinheit eine Aktualisierung anzeigt? Oder muss ich eine Eigenschaft der Bestellung aktualisieren, damit das Aktualisierungsdatum gesetzt wird?

Falls es einen Unterschied macht, ich benutze auch S#arp Architecture.

Hier ist der Codeblock, den ich verwende:

public class AuditEventListener : IPreUpdateEventListener, IPreInsertEventListener
{
    public bool OnPreUpdate(PreUpdateEvent @event)
    {
        var audit = @event.Entity as AuditedEntity;
        if (audit == null)
            return false;

        var time = DateTime.Now;

        Set(@event.Persister, @event.State, "UpdateDate", time);

        audit.UpdateDate = time;
        return false;
    }

    public bool OnPreInsert(PreInsertEvent @event)
    {
        var audit = @event.Entity as AuditedEntity;
        if (audit == null)
            return false;

        var time = DateTime.Now;

        Set(@event.Persister, @event.State, "CreateDate", time);
        Set(@event.Persister, @event.State, "UpdatedDate", time);

        audit.CreateDate= time;
        audit.UpdateDate= time;

        return false;
    }

    private void Set(IEntityPersister persister, object[] state, string propertyName, object value)
    {
        var index = Array.IndexOf(persister.PropertyNames, propertyName);
        if (index == -1)
            return;
        state[index] = value;
    }
}

2voto

Diego Mijelshon Punkte 52110

Wenn ich mich nicht irre, ist die Notes-Sammlung umgekehrt, order ist nicht verschmutzt, weshalb sie nicht gespeichert wird und daher auch nicht das PreUpdate-Ereignis auslöst.

Also ja... Sie müssen die Bestellung "anfassen", wenn Sie eine Aktualisierung erzwingen wollen.

0 Stimmen

Damit ist das Problem gelöst. Ich danke Ihnen. Jetzt muss ich nur noch herausfinden, wie ich der Bestellung sagen kann, dass sie schmutzig ist...

0 Stimmen

Wissen Sie, wie man an das Objekt "Order" herankommt? Im OnPreInsert/OnPreUpdate habe ich das @event-Objekt, das die OrderNote ist. Wenn ich debugge, kann ich das Order-Objekt sehen (indem ich mir die @event-Eigenschaften ansehe), aber ich möchte die UpdateTime für alle Aktualisierungen von Objekten, die mit der Order verknüpft sind, dynamisch auf die Order setzen... Etwas wie: (@event.Entity as IHasOrder).Order.UpdateDate = DateTime.Now; Ich denke, das würde tatsächlich funktionieren... aber ich muss eine Reihe von Entitäten mit IHasOrder ausstatten... alles, was zu einer Bestellung gehört...

1 Stimmen

Mit "manuell" meinte ich wirklich manuell . Das Ereignis OnPreInsert/Update kommt zu spät, um die übergeordnete Entität zu ändern.

0voto

Jamie Punkte 2838

Diego hatte also recht, dass die Bestellung berührt werden musste, um aktualisiert zu werden. Was ich letztendlich tat, war das Hinzufügen einer Schnittstelle IBelongToOrder zu allen Elementen, die Teil der Bestellung waren:

public interface IBelongToOrder
{
    Order Order { get; set; }
}

Dann haben alle Sammlungen der Bestellung diese Schnittstelle implementiert. Schließlich, die OnPreInsert/Update nur für diese Schnittstelle überprüft und entsprechend aktualisiert, wie:

var orderChild = @event.Entity as IBelongToOrder;
if (orderChild != null)
{
    orderChild.Order.UpdateDate = DateTime.Now;
}

Ich hoffe, das hilft jemandem, der herausfinden will, wie man Sammlungen in einer Arbeitseinheit aktualisiert...

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X