Frage

Ich habe eine DataMapper Klasse, das wird eifrig Last jede Eigenschaft, die keine faulen Attribut zu ihm angebracht hat. Ich habe zwei Entitäten, Staat und Land, Land haben eine inverse Beziehung in erklären, dass es sich um eine Liste aller Staaten dieses Landes enthält und Staat hat eine vordere Beziehung zu Land, dass es eine Eigenschaft Land hat, dass eifrige Lasten das Land, das es wird zugewiesen. Ich jedoch, wenn versuchen, eines dieser Objekte abzurufen, können Sie einen Staat sagen, das ist, was passiert:

  1. Staat wird geladen von Mapper
  2. Mapper erreicht ein eifrige Eigenschaft Land
  3. Mapper ruft das Land für diesen Zustand
  4. Mapper lädt das Land
  5. Mapper erreicht ein eifrige Sammlung Eigentum der Staaten
  6. Mapper lädt eine Liste von Staaten und beginnt jedes einzelne eine Abbildung des Cache verwenden, wo es kann.
  7. GOTO 1 für jeden Zustand in Land geladen

Ich bin ratlos, wie ich diese Schleife zu vermeiden. Also in erster Linie ich nach Ideen suchen. Ich werde keinen Code schreiben jemand fragt, aber dieser Prozess viel von Codezeilen umfasst, damit ich die Frage nicht mit Code zu überfluten wollte.

Vielen Dank im Voraus!

Edit:

In Ordnung nach Matt Howells Rat folgen und untersuchen tiefer in die DataMapper Muster Martin Fowler in der Tat über eine zyklische Referenz auf Seite spricht 169 und 170. Sein Vorschlag ist ein leeres Objekt zu verwenden und sie in eine Identitätskarte laden und senden Sie es so die rekursive Laden zu stoppen. Ich habe diesen Abschnitt über 1000mal jetzt gelesen und ich verstehe immer noch nicht, wie dies die Last stoppt und darüber hinaus, dass ich verloren, wann oder wie ich weiß, wann dieses leere Objekt in meine Identität Karte zu laden. Ich entschuldige mich für dichte, hier zu sein, aber dies scheint nur direkt über meinen Kopf zu fliegen.

Vielen Dank noch einmal.

War es hilfreich?

Lösung

Betrachten Laden von Objekten durch ein Repository, die Spur davon hält Objekte geladen wurden.

Edit: Wenn Sie Ihre eigene ORM tun (und auch wenn Sie nicht sind) I Martin Fowler Buch Patterns of Enterprise Application Architecture sehr empfehlen. Ich vage daran erinnern, ihn über diese Schleife Situation in dem Buch zu sprechen, so dass es Ihnen helfen könnte.

Edit 2: In den Schritten 4 und 5 von der Schleife, wenn Sie das Land bereits geladen haben, dann gibt es keine Notwendigkeit, eifrig seine Zustände geladen werden, da sie bereits geladen werden soll. Dies bricht die Endlosschleife.

Andere Tipps

Die DataMapper sollten zirkuläre Referenzen fangen. Ist es ein homegrown DataMapper?

Ich wollte nur die Lösung schreiben, die mich mit aufkommen, aber ich glaube, es gibt viele Möglichkeiten, diese Katze Haut.

Hier ist meine FetchDepthCounterClass ich erstellt:

public static class FetchDepthCounter
{
    private static Dictionary<Type, int> _DepthCounter;
    private static int _MaxDepth = 3;

    static FetchDepthCounter()
    {   
        _DepthCounter = new Dictionary<Type, int>();
    }

    public static void SetDepth(int depth)
    {
        _MaxDepth = depth;
    }

    public static void ResetCounter()
    {
        _DepthCounter.Clear();
    }

    public static bool IncrementCounter(Type entityType)
    {
        if(!_DepthCounter.ContainsKey(entityType))
        {
            _DepthCounter.Add(entityType, 0);
            return true;
        }

        if(_DepthCounter[entityType] < _MaxDepth)
        {
            ++_DepthCounter[entityType];
            return true;
        }

        return false;
    }

}

IncrementCounter gibt einen bool angegeben wird, ob die maximale Abruftiefe erreicht wurde oder nicht. Ich nenne Zähler erhöhen als Teil meines Mapping-Prozess, kurz bevor ich den Wert der Eigenschaft festgelegt. Zuerst bestimme ich, was ich bin mit einem anderen DTO-Objekt oder eine Sammlung von DTOs zu laden ist, und ich übergebe Sie die Eltern Art und Schritt auf diesem Typ. Das ist also das klein bisschen Code in meiner SetValue-Methode in meinem DataMapper:

if(isDto)
{
    if (!FetchDepthCounter.IncrementCounter(property.ComponentType))
        return;
}

Das ist es, dass es zu tun scheint. Alle meine Unit-Tests sind vorbei. Vielen Dank für die Hilfe aller. Ich hoffe, das hilft jemand später. Wieder einmal ist dies wahrscheinlich viel einfacher gewesen wäre, es in einer Arbeitseinheit Mustern Einwickeln und schließlich kann ich das tun, aber das wird die Arbeit für heute getan.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top