Frage

Ich habe eine EF Hierarchie bekam, die (dramatisch vereinfacht) etwa wie folgt aussieht:

class Room { EntityCollection<Session> Sessions; }
class Session { EntityCollection<Whiteboard> Whiteboards; EntityReference Room; }
class Whiteboard { EntityCollection<WhiteboardShape> WhiteboardShapes; EntityReference Session; }
abstract class WhiteboardShape { EntityReference Whiteboard; }
class WhiteboardShapeEllipse : WhiteboardShape { }
class WhiteboardShapePolyline { WhiteboardShape { EntityCollection<PolylinePoint> PolylinePoints }
class PolylinePoint { EntityReference<WhiteboardShapePolyline> WhiteboardShapePolylineReference; }

Mit anderen Worten kann ein Raum mehrere Sitzungen enthalten; Jede Sitzung kann mehrere Whiteboards enthalten; und jede Tafel kann mehrere WhiteboardShapes enthalten. Diese Formen können von verschiedenen Typen sein, einschließlich eines WhiteboardShapePolyline, die selbst mehrere PolylinePoints enthalten kann.

Wenn ein Remote-Benutzer zunächst auf den Raum verbindet, muß ich diesen Benutzer das gesamte Objektgraphen passieren, und ich versuche, herauszufinden, wie diese grafische Darstellung in den Speicher aus der Datenbank laden so effizient wie möglich.

Nun, natürlich erlaubt die EF für Sie gerne Laden zu tun, etwa so:

      Room room = ctx.Room
            .Include("Sessions.Whiteboards")
            .FirstOrDefault(r => r.OwnerID == ownerUserID && r.Name == roomName);

Aber include () hat mir die PolylinePoints laden nicht zulassen. Insbesondere dann, wenn ich versuche:

        Room room = ctx.Room
            .Include("Sessions.Whiteboards.WhiteboardShape.PolylinePoint")
            .FirstOrDefault(r => r.OwnerID == ownerUserID && r.Name == roomName);

ich die Ausnahme erhalten „A angegebene Include-Pfad nicht gültig ist. Die EntityType‚SlideLinc.Model.WhiteboardShape‘deklariert keine Navigationseigenschaft mit dem Namen‚PolylinePoint‘.“

Auch funktionierts:

.Include("Sessions.Whiteboards.WhiteboardShapePolyline.PolylinePoint")

auch nicht so aus:

.Include("Sessions.Whiteboards.WhiteboardShape.WhiteboardShapePolyline.PolylinePoint")

Auch eine andere Möglichkeit, den Navigationspfad von Rahmen, die ich mir vorstellen kann.

Die Art und Weise, dass ich beendet habe, um es sicher zu tun scheint wie ein Hack zu mir:

        // Make sure we've got everything loaded.
        if (room != null)
        {
            if (!room.Sessions.IsLoaded) { room.Sessions.Load(); }
            foreach (Session session in room.Sessions)
            {
                if (!session.Whiteboards.IsLoaded) { session.Whiteboards.Load(); }
                foreach (Whiteboard whiteboard in session.Whiteboards)
                {
                    if (!whiteboard.WhiteboardShape.IsLoaded) { whiteboard.WhiteboardShape.Load(); }
                    foreach (WhiteboardShape shape in whiteboard.WhiteboardShape)
                    {
                        if (shape is WhiteboardShapePolyline)
                        {
                            WhiteboardShapePolyline polyline = (WhiteboardShapePolyline)shape;
                            if (!polyline.PolylinePoints.IsLoaded) { polyline.PolylinePoints.Load(); }
                        }
                    }
                }
            }
        }

Es funktioniert, aber es ist viel mehr Code als ich will, und es ist eine ganze Menge mehr Datenbank zugreift, als ich will.

Die nächste Antwort, die ich gefunden habe, ist hier , aber meine arme Linq- ausgehungert Gehirn kann nicht herausfinden, wie das Beispiel-Code in die kompliziertere Hierarchie zu übersetzen, die ich habe; plus, der Beispielcode zu diesem Link ist verdammt hässlich und schwer zu verstehen. Ich weiß nicht wirklich meine ganze Objekthierarchie will in Abhängigkeit von einem dunkelen und unsichtbaren Nebeneffekt, wie das EF seiner Hierarchien intern konstruiert.

Alle anderen Vorschläge?

War es hilfreich?

Lösung

Ich würde wahrscheinlich Projektion für diese. Stattdessen Entitätstypen, Projekt auf leichte Datentransferobjekte oder anonyme Typen zurückzugeben. Wenn Sie (zum Beispiel mit einer LINQ-Abfrage) projizieren, geschieht der Laden automatisch. Sie müssen in diesem Fall nicht ein Fügen Sie angeben.

Andere Tipps

Ich habe gerade ein ähnliches Problem bei Ihnen (einfacher naviagation Pfad) und ich erkennen, dass die Property in der Designer.cs Datei war nicht das, was ich erwartet habe. Sobald ich es dem Property in der Designer-Datei verändert es gut geklappt - auch bemerke ich zwei verschiedene Pfade haben, die wurde:

.Include("UnexpectedNameA").Include("UnexpectedNameB")
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top