2015-06-14 7 views
5

Sto leggendo su repository generici. Continuo a inciampare in pezzi di codice che non capisco. Non so se c'è un nome specifico per loro o no.Come si chiama e cosa fa? (Parte di un deposito generico)

Questo è l'esempio più complicato che ho visto:

IEnumerable<T> GetByQuery(
    Expression<Func<T, bool>> query = null, 
    Func<IQueryable<T>, IOrderedQueryable<T>> orderby = null, 
    string includeProperties = ""); 

So che (qualunque esso sia) apparentemente restituisce un IEnumerable, ma non ho idea di come leggere quel casino di testo confuso non parlare di come per usarlo.

Modifica: Sono più interessato a sapere che cosa è un esempio di di una ripartizione di quello specifico esempio. Devo sapere come sono chiamati prima di poter trovare qualcosa che spieghi la sintassi. LINQ ??

Modifica 2: sto facendo una domanda molto più semplice di quella a cui è stata data risposta. Tutto quello che voglio sapere è "quali sono i termini di ricerca che posso utilizzare per cercare il codice sopra?"

+0

Mi piace che hai usato "gobbledygook" - Le espressioni possono sembrare disordinate –

+0

Devi essere un po 'più specifico su quali parti del gook sono gobbledy. Sai cosa sono i farmaci generici? Sai cos'è un delegato? Sei confuso su come 'IQueryable ' funziona? Non capisci il bit di 'Expression <>'? C'è una risposta eccellente che abbatte già questo particolare metodo, ma forse quei termini aiuteranno a guidare la tua ricerca di base. –

+0

Ho sentito parlare di generici e delegati. Non ho mai visto nulla con i termini IQueryable, Func o Expression <> prima. L'unica 'espressione' che abbia mai sentito parlare di matematica (come in 2 + 2). Sto assumendo anche se c'è un contesto specifico in cui queste cose si verificano insieme. Questo è quello che sto cercando di capire. – rayden54

risposta

9

Nota: si tratta di un'ipotesi estremamente istruita, basata su come funziona IQueryable<T>.

scomponendola in tre parti:

Expression<Func<T, bool>> query = null 

Si tratta di una clausola in cui, è la stessa firma che è passato al metodo Where estensione IQueryable<T>.

Si passerebbe un'espressione, che è rappresentata in codice nello stesso modo in cui è una lambda; il compilatore C# sa che il parametro sta cercando un Expression e lo compila in un albero di espressioni e non in un delegato.

Per esempio, assumendo T è una classe Person con una int proprietà Age, si potrebbe filtrare qualsiasi Person restituito dal IQueryable<Person> che è di 30 anni o più con il seguente:

p => p.Age > 30 

Func<IQueryable<T>, IOrderedQueryable<T>> orderBy 

Questo è solo un delegato che, se fornito, ti consentirà di impostare un ordine. Supponendo che si desidera che i Person casi in ordine di età, utilizza:

q => q.OrderBy(p => p.Age) 

Questo perché il tipo di ritorno è IOrderedQueryable<T>, che come metodi di estensione, come ThenBy e ThenByDescending pop-up solo dopo aver chiamato OrderBy e OrderByDescending; quei metodi di estensione sono definiti solo su IOrderedQueryable<T> (è poco più di un'interfaccia marcatore).


includeProperties 

Questo dà via che sta utilizzando Entity Framework sotto le coperte. Quando si chiama Include in Entity Framework, consente di ottenere entità correlate (tramite chiave esterna) e caricare le entità correlate all'entità restituita nella query.

Supponiamo che la classe Person abbia una proprietà Father di tipo Person. Se si desidera eseguire query sulle istanze Person e restituire anche la proprietà Father, è necessario chiamare Include("Father") per indicare che Entity Framework non solo deve ottenere le istanze di Person, ma dovrebbe anche risolvere la relazione Father.


IEnumerable<T> tipo di ritorno

Questo viene restituito in modo che non si ha accesso all'istanza IQueryable<T> e ti costringe a materializzare il set di risultati (come eseguire iterazioni attraverso di esso).

Una realizzazione che fa questo dovrebbe ritorneremo l'una lista (IReadOnlyCollection<T>) materializzato, o qualcosa che non è solo (assumedly) un cast di IQueryable<T>-IEnumerable<T>.

È anche un'indicazione della fiducia che lo scrittore del metodo ha per i clienti; come IQueryable<T> non viene restituito, indica che non si fida dei client per non effettuare chiamate di database inefficienti (che è un problema valido).

+3

Devo notare che è mia opinione che il metodo in questione sia decisamente un ostacolo; sta davvero rendendo l'uso di Entity Framework molto più difficile. Quello che dovresti fare idealmente è accedere a un 'IQueryable ' (con qualche configurazione dei filtri/ordinamenti di base) e lasciare che il chiamante materializzi la lista da solo, opzionalmente aggiungendo qualche logica/operazioni di query aggiuntive prima di farlo. – casperOne

+0

Non so nemmeno che cos'è, temo. – rayden54

+2

@ user2146821 se non capisci questa risposta, che è abbastanza chiara e una buona interruzione, hai qualche ricerca di base da fare. – usr