Ho, diciamo, un database contenente tabelle Forum e argomenti. Ogni argomento ha una chiave estranea al suo forum genitore.
I loro modelli C # associati sono Forum e Topic e Forum ha un ICollection che punta ai suoi argomenti figli. Ho un repository del forum che uso per accedere direttamente al contesto dell'entità framework e restituisco solo Forum / IEnumerable da esso. Il resto dell'applicazione accede solo al database attraverso questo repository. La mia domanda è la seguente: ad un certo punto nel tempo, voglio ottenere, diciamo, tutti i forum dal database senza inserire la proprietà Argomenti. Per fare questo, dovrei avere un metodo GetAll che farebbe questo: return _context.Forums.ToList () ;.
Ma ora supponiamo che voglio anche a un certo punto restituire tutti i forum, ma con la loro proprietà Argomenti popolata. Immagino di poter creare un nuovo metodo nel repository (chiamato GetAllForumsWithTopics o qualcosa del genere), ma sembra strano creare un nuovo metodo ogni volta che voglio includere più campi (forse a un certo punto voglio anche includere una proprietà per l'argomento , dì la sua lista di post .. quindi dovrei andare come GetAllForumsWithTopicsWithPosts?).
Quindi, mi piacerebbe in qualche modo definire un metodo GetAllForums ("includelist") [EDIT: In realtà non mi piacerebbe una stringa come parametro, ma un espressione lambda :)] metodo che mi permetterebbe di includere le proprietà lungo la gerarchia (non solo per i forum stessi). Quale sarebbe un buon modo per farlo?
Probabilmente è una buona idea scrivere il codice che stai tentando di fare. Il modo in cui sto leggendo questo è che hai qualcosa di simile al seguente:
public class Forum
{
public int Id {get; set;}
public IEnumerable<Topic> Topics {get; set;}
}
public class Topic
{
public int Id {get; set;}
public Forum Forum {get; set;}
}
Ci sono alcuni modi per risolvere questo. Sembra che tu sappia già la differenza tra Virtual e Non-Virtual, quando si tratta di quanto entusiasta carica i contenuti. È possibile includere in modo selettivo elementi figlio utilizzando la proprietà Include (consultare: https://msdn.microsoft.com/en-us/library/jj574232(v=vs.113).aspx )
Personalmente, il percorso che probabilmente avrei affrontato è nella mia classe di implementazione EF (che implementa un'interfaccia usata altrove) per avere due metodi get:
public virtual IQueryable<Forum> Forums => _context.Forums;
public virtual IQueryable<Forum> ForumsWithChildren => _context.Forums.Include(m => m.Topic)
In un'applicazione "reale" di questo, ci dovrebbe essere un limitatore di tempo, e solo tirando gli argomenti da una specifica chiamata sul forum:
public virtual Forum GetForumWithRecentPosts(int id)
{
//Add where clause to restrict based off date.
return Forums.Where(x => x.Id == id).include(m => m.Topic);
}