2012-10-02 15 views
7

AmbienteEF/LINQ Come includere entità figlio quando v'è una relazione bidirezionale

Sto usando Entity Framework 5 su Framework 4.0. (Questo significa che sto effettivamente usando EF 4.4). Come entità utilizzo STE (Self Tracking Entities) perché sto lavorando in un'applicazione N-Tier. Utilizziamo un approccio basato su database perché EF è stato introdotto più avanti nel gioco.

Contesto

Ho 2 Entità che entrambi hanno una proprietà di navigazione per l'altro. (EntityA ha una proprietà di navigazione per EntityB e EntityB one per EntityA). La relazione è "EntityA> One-To-Many> EntityB". Quando voglio caricare le entità figlio tramite un'espressione LINQ, ho bisogno di usare INCLUDE (STE => Eager Loading) perché passerò tutti i dati attraverso diversi livelli.

Il codice

Ecco il mio codice per chiamare EntityA con i suoi figli EntityB.

using (var ctx = new MyEntities()) 
{ 
    var result = (from s in ctx.EntityA.Include("EntityB") 
        where s.Id = 11111 
        orderby s.TimeUpdated descending 
        select s) 
       .Take(10) 
       .ToList(); 
    return result; 
} 

L'errore

System.StackOverflowException {Impossibile valutare l'espressione perché il thread corrente è in uno stato di overflow dello stack.}

Non v'è alcun errore quando rimuovo il 'INCLUDE'. Immagino che la ragione sia semplice. Desidero caricare EntityA con i record figlio EntityB, i record EntityB vogliono caricare la sua entità padre EntityA ogni volta, e EntityA ... Suppongo che tutti comprendano il ciclo infinito qui.

mie soluzioni o alternative

  • vado al mio file EDMX e rimuovere la proprietà di navigazione per EntityA in EntityB. Se ora voglio caricare i dati su EntityA mentre ho un EntityB a mia disposizione. Devo fare una richiesta DB separata e ho 2 oggetti diversi che devo passare attraverso i miei livelli.
  • Evitare di utilizzare include, caricare separatamente EntityA e inserirlo nella proprietà Navigation della mia EntityB che fa riferimento alla mia EntityA.

la questione

sono alternative migliori là o approcci per risolvere questo problema nella mia situazione? Devo andare avanti con una delle mie alternative che ho proposto o no? Perché speravo in una soluzione migliore e più pulita.

vi ringrazio per il vostro tempo

Ian

+1

+1 Per un ottimo (1 °) domanda per voi. –

+0

Ho provato a riprodurre il problema in EF 5 (Visual Studio 2012) e non ho alcun errore. C'è qualcos'altro che potrebbe causare il tuo problema? Funziona con una semplice configurazione POCO? (Sidenote .. Ho già lavorato con STE e ora sto davvero cercando di evitarli. Sei sicuro di voler usare STE?) –

+0

Non riesco a riprodurre l'errore neanche (EF5, .NET 4.0). È possibile pubblicare lo stacktrace e magari cancellare i dati sensibili? –

risposta

1

Ho provato a riprodurre il problema in EF 5 (Visual Studio 2012) e non ho alcun errore. C'è qualcos'altro che potrebbe causare il tuo problema? Funziona con una semplice configurazione POCO?

Volevo anche notare che STE può darti un certo mal di testa. Ho lavorato con STE prima e ora sto davvero cercando di evitarli. Sei sicuro di voler usare STE?

Invece di utilizzare STE, è possibile utilizzare semplici DTO vecchi. Manterrai il tuo modello di dominio ricco sul server e invierai solo i dati necessari al client. In questo modo è possibile creare DTO personalizzati con la minor quantità di dati per ogni caso d'uso.

0

Sono venuto qui per dire a voi "È possibile utilizzare Include" ma ovviamente non ti aiuta in questa situazione.

Come ho letto su internet di solito, non v'è alcune soluzioni quando abbiamo il sospetto (o avere) un caso ciclo infinito:

  1. Possiamo usare Load operazioni utilizzando foreach e caricare i bambini manualmente.
  2. Possiamo creare un database view that is a recursive query da solo (e utilizzare la sua entità).
+0

- 1. Le operazioni di caricamento non possono essere applicate perché le mie proprietà di navigazione non sono _EntityCollections _ ma _TrackableCollection _ - 2. Saddly questo non si applica al mio contesto. Ad esempio, desidero accedere facilmente all'entità padre (EntityA) e salvarlo come campo della mia entitàB. Ho testato 'context.LoadProperty (EntityB, "EntityA")' Ma genera anche la stessa StackOverflowException. Grazie per i suggerimenti –

0

see this

però ho aggiornamento 4 installato e ancora non è possibile eseguire il debug

Problemi correlati