Question

J'ai une hiérarchie EF qui (de façon spectaculaire simplifiée) ressemble à quelque chose comme ceci:

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

En d'autres termes, une salle peut contenir plusieurs sessions; chaque session peut contenir plusieurs tableaux blancs; et chaque Whiteboard peut contenir plusieurs WhiteboardShapes. Ces formes peuvent être de différents types, y compris un WhiteboardShapePolyline, qui lui-même peut contenir plusieurs PolylinePoints.

Lorsqu'un utilisateur distant se connecte d'abord à la salle, je dois passer tout le graphe d'objet à cet utilisateur, et je suis en train de comprendre comment charger ce graphique à partir de la base de données en mémoire le plus efficacement possible.

Maintenant, bien sûr, l'EF permet pour vous de faire le chargement désireux, comme ceci:

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

Mais Include () ne me laisse pas charger les PolylinePoints. Plus précisément, si je tente:

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

Je reçois l'exception « A spécifié Inclut le chemin n'est pas valide. Le EntityType « SlideLinc.Model.WhiteboardShape » ne déclare pas une propriété de navigation avec le nom « PolylinePoint ». »

Il ne fait ce travail:

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

ne fait ceci:

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

ni aucune autre façon d'encadrer le chemin de navigation que je peux penser.

La façon dont je l'ai fini par le faire que semble comme un hack pour moi:

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

Il fonctionne, mais il est beaucoup plus de code que je veux, et il est plus base de données tout un tas accès que je veux.

La réponse la plus proche que j'ai trouvé est , mais mon pauvre Linq- cerveau affamée ne peut pas comprendre comment traduire le code exemple dans la hiérarchie plus complexe que j'ai; De plus, l'exemple de code à ce lien est damnée laid et difficile à comprendre. Je ne veux pas vraiment hiérarchie mon objet entier selon un obscur et invisible effet secondaire de la façon dont l'EF construit en interne ses hiérarchies.

Toutes les autres suggestions?

Était-ce utile?

La solution

Je serais probablement utiliser la projection pour cela. Au lieu de renvoyer les types d'entités, projet sur des objets de transfert de données légers ou des types anonymes. Lorsque votre projet (par exemple, avec une requête LINQ), le chargement se fait automatiquement. Vous n'avez pas besoin de spécifier une Inclure dans ce cas.

Autres conseils

Je viens d'avoir un problème similaire à la vôtre (plus facile chemin de naviagation) et je me suis aperçu que le NomPropriété dans le fichier Designer.cs était pas ce que je pensais. Une fois que je l'ai changé au NomPropriété dans le fichier Designer tout fonctionnait bien - noter aussi que je l'ai fait deux chemins différents qui sont devenus:

.Include("UnexpectedNameA").Include("UnexpectedNameB")
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top