2009-03-10 10 views
54

Inizio a utilizzare LINQ in generale (fino aXML e toSQL). Ho visto che a volte ci sono due o più modi per ottenere gli stessi risultati. Prendi questo semplice esempio, per quanto ho capito sia restituiscono esattamente la stessa cosa:LINQ: notazione dei punti rispetto all'espressione di query

SomeDataContext dc = new SomeDataContext(); 

var queue = from q in dc.SomeTable 
     where q.SomeDate <= DateTime.Now && q.Locked != true 
     orderby (q.Priority, q.TimeCreated) 
     select q; 

var queue2 = dc.SomeTable 
     .Where(q => q.SomeDate <= DateTime.Now && q.Locked != true) 
     .OrderBy(q => q.Priority) 
     .ThenBy(q => q.TimeCreated); 

Oltre a qualsiasi errore che può aver fatto nella sintassi o di un parametro mancante o differenza, l'idea è che ci sono due modi per esprimere la stessa cosa; Capisco che il primo metodo ha alcune limitazioni e che la "notazione dei punti" è più completa, ma oltre a ciò, ci sono altri vantaggi?

+0

Grazie a tutti per le risposte. Ahimè, posso segnarne solo una come risposta corretta. Ma apprezzo tutti i commenti. –

+1

Duplicato: http://stackoverflow.com/questions/214500/which-linq-syntax-do-you-prefer-fluent-or-query-expression – Mikhail

risposta

48

La notazione "punto" è di solito chiamato sintassi Lambda. La prima notazione ha un certo numero di nomi, ma di solito la chiamo sintassi della query.

Io lavoro su un team di 10 sviluppatori e discutiamo a lungo su quale dovrebbe essere usato come standard. In generale, gli sviluppatori più esperti (con LINQ) migrano verso la sintassi Lambda ma ci sono eccezioni significative.

Lambda è più conciso ma eseguire più join di tabelle è un incubo. I join sono molto più puliti con la sintassi della query. Il rovescio della medaglia è che ci sono un certo numero di operazioni LINQ che esistono solo all'interno della sintassi Lambda: Single(), First(), Count() ecc.

Quindi, usa ciò che ti senti più a tuo agio e rendilo conto che acquisisci esperienza, la tua preferenza cambierà probabilmente. C'è un grande valore nella possibilità di leggere entrambi e ci saranno certamente situazioni in cui devi usare un po 'di entrambi. Altre situazioni si prestano a uno stile rispetto all'altro. Alla fine, tutto viene tradotto nello stesso codice eseguibile.

+1

5 anni più tardi e la sintassi lambda concatenata con metodo è ora comunemente chiamata [Fluent Interface] (http://en.wikipedia.org/wiki/Fluent_interface). – Nick

8

Bene, la notazione 'punto' può essere molto più breve. Prendere:

var result = from p in dc.Products 
      where p.Id > 5 
      select p; 

o:

var result = dc.Products.Where(p => p.Id > 5); 

preferisco quest'ultimo dal momento che è molto più breve e più leggibile.

+0

Quando si utilizza LINQ to SQL, preferisco il primo perché è più vicino a T- SQL (utile quando si scrivono query DB) e il secondo per altre query LINQ (come LINQ in XML). – RobS

+0

Sì, hai un punto lì. Con linq2sql uso spesso la prima versione, per lo stesso motivo che hai menzionato. Anche se devo ammettere che per query molto semplici come quella sopra, uso spesso la seconda versione breve, solo perché sono pigro :-) – Razzie

+0

Non è SEMPRE più breve, ea volte è più difficile da leggere, ma tu hai un indica che può essere un po 'più breve. –

2

Compilano lo stesso codice, o piuttosto il primo viene prima tradotto al secondo e poi compilato.

Hai ragione che la differenza è che la prima versione è più pulita ma più limitata. Nel secondo si può ad esempio utilizzare delegati già esistenti, ad es .:

Func<int, bool> isEven = i => i%2 == 0; 
Enumerable.Range(10).Where(isEven).ToList().ForEach(Console.WriteLine); 
+0

Non completamente vero. È possibile utilizzare ancora un delegato esistente, ad esempio: var result = from s nell'elenco dove isEven.Invoke (s.Length) select s; – Razzie

+0

sì, ma parlando di stile * .Invoke è semplicemente brutto :) – user76035

+1

non è necessario utilizzare Invoke, questo funziona bene: var result = da i in in cui isEven (i) select i; – theburningmonk

27

Uso la sintassi che è più leggibile per la mia query, caso per caso.

Dove possibile, cercare di evitare la miscelazione e la congruenza due, anche se a volte va bene (se si tratta di una singola chiamata a First() al termine di una query, per esempio). esecuzione differita significa che è altrettanto efficiente utilizzare un'espressione di query e assegnare il risultato a una variabile, e quindi utilizzare la notazione utilizzando tale variabile:

var query = from x in y 
      orderby z 
      group x by x.Name into groups 
      // etc 
      select foo; 

var page = query.Skip(50).Take(10); 

Come altri hanno già detto, le espressioni di query stanno tradotti in " normale "C# 3 senza espressioni di interrogazione, quindi non c'è penalità per farlo.

+3

+1 di nuovo per dividere i due quando vuoi usarli insieme invece di avvolgere il primo tra parentesi e attaccare il resto alla fine. – Shibumi

3

Trovo la notazione Lambda più ordinata e più concisa.Trovo semplicemente fastidioso che se si dispone di un'espressione Lambda in qualsiasi punto all'interno di una chiamata di metodo, non è possibile modificare il codice al volo in modalità di debug ...

+0

Il comando Modifica e continua funziona se si utilizzano le espressioni di query? –

+0

@MichaelFreidgeim - No. :-) Una delle cose che ho scoperto nei 2 anni dopo aver scritto questa risposta. –