Domanda

Ho una gerarchia EF che (drasticamente semplificato) simile a questa:

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

In altre parole, una stanza può contenere più sessioni; ogni sessione può contenere più lavagne; e ogni Lavagna può contenere più WhiteboardShapes. Queste forme possono essere di vario tipo, tra cui un WhiteboardShapePolyline, che può anche contenere più PolylinePoints.

Quando un utente remoto si connette inizialmente alla camera, ho bisogno di passare l'intero grafo oggetto a tale utente, e sto cercando di capire come caricare tale grafico dal database in memoria nel modo più efficiente possibile.

Ora, naturalmente, l'EF permette per voi di fare eager loading, in questo modo:

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

Ma include () non mi permette di caricare il PolylinePoints. In particolare, se provo:

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

Ho l'eccezione "A specificato Include percorso non è valido. L'EntityType 'SlideLinc.Model.WhiteboardShape' non dichiara una proprietà di navigazione con il nome di 'PolylinePoint'."

Né questo lavoro:

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

Né questo:

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

né alcun altro modo di inquadrare il percorso di navigazione che mi viene in mente.

Il modo in cui ho finito per fare di sicuro sembra come un trucco per me:

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

Funziona, ma è molto di più di quanto il codice che voglio, ed è un sacco di più accessi al database di quanto io voglio.

La risposta più vicina che ho trovato è qui , ma il mio povero Linq- cervello fame non riesce a capire come tradurre il codice di esempio nella gerarchia più complicata che ho; Inoltre, il codice di esempio in quel collegamento è dannata brutto e difficile da capire. Non voglio davvero la mia intera gerarchia di oggetti in funzione di un effetto collaterale oscuro e invisibile come l'EF costruisce internamente le sue gerarchie.

Altri suggerimenti?

È stato utile?

Soluzione

Io probabilmente utilizzare proiezione per questo. Invece di restituire tipi di entità, progetto su oggetti di trasferimento dati leggeri o tipi anonimi. Quando si proietta (ad esempio, con una query LINQ), il caricamento avviene automaticamente. Non è necessario specificare un include in questo caso.

Altri suggerimenti

Mi stavo avendo un problema simile al tuo (più facile percorso naviagation) e mi sono reso conto che il PropertyName nel file Designer.cs non era quello che mi aspettavo. Una volta ho cambiato il PropertyName nel file Designer tutto ha funzionato bene - anche notare che ho fatto due percorsi diversi che divennero:

.Include("UnexpectedNameA").Include("UnexpectedNameB")
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top