2009-09-03 18 views
10

Le mie domande sono probabilmente molto semplici, come si caricano i bambini/sottoclassi. Non c'è "carico" o qualcosa di simile che posso trovare per avere il contesto caricare i bambini.Entity Framework 3.5 - Come caricare i bambini

classe contesto è di tipo ObjectContext, vedere sotto:

public partial class RTIPricingEntities : global::System.Data.Objects.ObjectContext 

prodotto

Product.ModifiedByUser (come caricare questa classe, durante il caricamento del prodotto ??)

prodotto .Category (come caricare le categorie quando si carica il prodotto?)

+0

Ecco un esempio di come sto caricando i dati: Forse avrei dovuto dire che sto codificando questo per un'applicazione Silverlight. E questo è attraverso un servizio di dominio. RTIPricingContext _context = new RTIPricingContext(); LoadOperation op = _context.Load (context.GetPurchaseOrderQuery(), PurchaseOrdersLoadedCallback, null); PurchaseOrdersLoadedCallback private void (LoadOperation lo) { IEnumerable po = lo.Entities.Where (w => w.UserID == SelectedUser.ID); // Questa è la raccolta su cui ho bisogno di compilare le sottoclassi. – Jukeman

risposta

16

È possibile caricare ansiosi:

var q = from p in Context.Products 
        .Include("ModifiedByUser") 
        .Include("Category") 
     select p; 

... o progetto:

var q = from p in Context.Products 
     select new 
     { 
      Id = p.Id, 
      Name = p.Name 
      ModifiedByUserName = p.ModifiedByUser.Name, 
      CategoryName = p.Category.Name 
     } 

Il vantaggio di proiezione è si ottiene solo i dati necessari, non tutta di ogni entità di riferimento. Il vantaggio del caricamento ansioso è che le entità restituite cambiano il tracciamento. Scegli la tecnica giusta per il problema in questione.

Aggiornamento

Sì, è importante ricordare che si sta utilizzando RIA Services. Presumo che tu stia lavorando anche all'interno del client. Questo rende le cose completamente diverse.

In Servizi RIA, è molto importante assicurarsi di restituire l'intero grafico delle entità necessarie nel carico iniziale. Non vuoi chiamare nulla come .Load() su un'entità, perché sarebbe un altro caldo per il server, il che è negativo per le prestazioni. Se, ad esempio, ci si trova in un client Silverlight e si richiede un elenco di istanze dal server e le relative proprietà non sono già materializzate, è già troppo tardi. Inoltre, l'inclusione non funzionerà in un client Silverlight. Pertanto, i Servizi RIA dispongono di strumenti sul lato server che è possibile utilizzare per garantire che si restituisca inizialmente il grafico corretto e completamente materializzato dell'oggetto.

Quello che è necessario invece è utilizzato IncludeAttribute all'interno del server dei servizi di RIA. Puoi creare una classe di metadati "amici" per decorare il tuo modello di entità con [Includi]. Ci sono esempi in the RIA Services overview document, section 4.8.

+0

Ciao, non so se abbiamo la stessa versione, ma nessuna delle due opzioni è possibile quando la codifico. Non c'è ".Include" disponibile, solo "Interseca" .. im usando entità derivate da entità che ha "ObjectContext" come sua classe base .. E quando progetto, non ci sono proprietà nell'intelligenza che io possa impostare .. – Jukeman

+1

Includi è un metodo di ObjectQuery , non IQueryable . Quindi controlla il tipo di riferimento che hai. Le entità non derivano da ObjectContext, derivano da EntityObject. Nel mio esempio non ci sarà alcun IntelliSense sull'oggetto proiettato perché ho usato un tipo * anonymous *. Se avessi usato un tipo non anonimo, ci sarebbe IntelliSense. –

3

È possibile utilizzare il metodo Include() dello System.Data.Objects.ObjectQuery. Questo metodo specifica gli oggetti correlati da includere nei risultati della query e le chiamate a Include() possono essere concatenate per caricare più oggetti correlati.

Ad esempio per caricare ModifiedByUser e ad una categoria si usa una query come questa:

var q = from p in context.Products.Include("ModifiedByUser").Include("Category") 
     select p; 

Se il soggetto categoria ha avuto anche un'entità ModifiedByUser che si voleva caricare si usa una query come questa:

var q = from p in context.Products 
       .Include("ModifiedByUser") 
       .Include("Category.ModifiedByUser") 
     select p; 

Vedere Shaping Query Results su MSDN per ulteriori esempi.

+0

Vedo questa soluzione un po ', quindi devo fare qualcosa di totalmente diverso da tutti gli altri. Fondamentalmente, sto usando il contesto dal datamodel che è stato generato dal entityframework. Ho l'ultimo di .Net. Non è disponibile l'opzione "Includi". Stai usando dbml/linq in questo esempio?Sto pensando che sia per questo che è diverso ... – Jukeman

7

Utilizzare lo .Include() come molti altri hanno suggerito è un ottimo modo per ottenere ciò di cui hai bisogno.

Tuttavia, a volte potrebbe essere necessario "ricaricare" in seguito qualcosa che non è stato "incluso" o che è necessario solo a volte, quindi inserire un'istruzione Includi potrebbe essere uno spreco di cicli di elaborazione in molti casi .

In caso di una relazione singolare come "Product.Category" (dove Product.Category è la proprietà di navigazione da prodotto a categoria), è probabile che sia presente anche un elemento "Product.CategoryReference". È possibile verificare che per vedere se è carica o no, e se no, si può caricare "on demand":

if(!Product.CategoryReference.IsLoaded) 
{ 
    Product.CategoryReference.Load(); 
} 

Ora il vostro riferimento "Categoria" dovrebbe essere in memoria e pronto per l'uso.

Se si dispone di una proprietà di navigazione che fa riferimento a un insieme di cose (per esempio, "Parti" per un prodotto), si può fare la stessa cosa, direttamente sulla proprietà di navigazione:

if(!Product.Parts.IsLoaded) 
{ 
    Product.Parts.Load(); 
} 

che può essere un tecnica utile per "caricare su richiesta" di proprietà di navigazione di tipo singolo o di raccolta se non le hai "incluse" nella tua query EF.

Marc

+0

Grazie a tutti, ho capito che il motivo per cui non ero in grado di implementare le molte soluzioni proposte è perché il contesto è diverso una volta convertito dal servizio di dominio per Silverlight. Nel codice sottostante del modello di dati del framework di entità posso implementare tutte le tue soluzioni e l'ho appena scoperto. Ma grazie al tuo aiuto, sapevo che il problema doveva essere che stavo cercando nel posto sbagliato ... – Jukeman

0

ho notato che la soluzione sopra menzionato da Craig non carica sia il ModifiedByUser e ad una categoria. Carica solo l'ultima raccolta di oggetti che in questo caso è "Categoria".

var q = from p in Context.Products 
       .Include("ModifiedByUser") 
       .Include("Category") 
    select p; 

Tuttavia, se si scambia l'ordine, per renderlo .Include("Category").Include("ModifiedByUser"), quindi ModifiedByUser viene caricato. La cosa strana è che la proprietà IsLoaded di entrambi gli oggetti mostrerà "true", tuttavia il conteggio per la prima raccolta di oggetti sarà sempre zero. Non sono sicuro del motivo per cui questo è il caso.

Problemi correlati